JXTA Java Standard Edition v2.5 Programmers Guide中文翻译(二)

1222阅读 0评论2012-02-17 小尾巴鱼121121
分类:

第六章 基础知识
    这一章根据手册中描述的编程实例所需的编译、运行的相关步骤讨论了JXTA开发的相关开发环境。

开始

系统要求
    当前的JXSE实现需要5.0版或更高的JRE和SDK。JRE和JDK当前对于Solaris系统、Moicrosoft Windows、Linux、Mac OS X和其它部分操作系统都是可用的。你可以为这些系统从甲骨文的网站下载所对应的JDK版本。

访问在线文档
    你可以访问JXTA JXSE API的在线文档。(没找到……)
    
下载二进制文件
    从官方站点下载JXSE的配套编程手册(不知道是不是SUN被收购的原因,我没找到JXSE的手册项目,听了吗?可以在这找些JXSE的资源)。这个压缩文档中包含了教程的源码和二进制发布。
    你可以从网站下载JXTA的当前版本。这个站点提供了JXTA的几个版本:
    通常下载的JXTA的源码同样允许你自己编译。你可以从下载源代码,用来编译你自己的JXTA二进制文件。

编译JXTA代码
    例子中的HelloWorld程序在编译时需要jxta.jar文件包。当你运行Java编译程序(javac)时,你需要使用-classpath参数来指定jxta.jar文件的位置。你将需要提供jxta.jar文件在你系统上的具体位置。
    编译命令的例子(Windows systems):
    C:>javac -classpath .\lib\jxta.jar IDTutorial.java

运行JXTA程序
    当你输入java命令运行程序的时候,你需要使用-classpath参数指定所需的jar文件的位置。你将需要提供所需的.jar文件的具体位置。
    程序运行命令例子(Windows systems):
    C:>java -classpath .\lib\jxta.jar;.\lib\bcprov-jdk14.jar;. IDTutorial
    JXSE包含一个简单的用户界面的配置。多数情况下这种默认的配种会被使用编程性的平台配置替代,例如作为NetworkConfigurator类或通过使用NetworkManager类,需要进行的预先的概要配置:
  1.     Ad-Hoc:这种节点在点对点网络中是典型的部署。这个节点不会使用基础设施节点(集合节点或中继节点)。
  2. 边缘节点——除了支持Ad-Hoc的行为,一个边缘节点还会依附于一个基础设施节点(集合节点、中继节点或这两者)。
  3. 集合节点——支持网络初期引导服务,例如发现,管道解析等。
  4. 中继节点——提供信息中继服务,使其能穿越防火墙。
  5. 代理节点——为J2ME代理服务提供JXME JXTA。
  6. 超级节点——提供集合节点、中继节点、代理节点的所有功能。
    强烈推荐JXTA节点通过NetworkManager或NetworkConfigurator类的静态静态方法进行节点配置,被期望使用的方法例如newEdgeConfiguration(storeHome)。一旦配置被创建,它可能会符合程序的要求。
    NetworkConfigurator可以使用一个给定的URI载入配置的能力也是值得注意的。它的一个特点是为提供节点的PeerID和节点证书提供了系统的方法。例如,load("");

“公共JXTA网络”配置参数
    在一些例子中可能会用到JXTA开发网络,以用来支持初始示例程序和教程。它们并不打算在生产网络中被使用。这个配置是用来对运行在本地多子网、防火墙、NATs环境中的JXTA程序进行测试。
 
JXTA和HTTP代理
    为了能让JXTA节点穿过防火墙进行连接,JXTA支持使用HTTP代理。它们是被web浏览器所使用的代理相同的代理。一些代理被配置为需要认证。大多数情况下,Java程序在安装的时候JXTA会使用系统HTTP代理配置参数或者是使用提供的配置。你也可以通过Java控制台调整HTTP代理设置。

我需要代理吗?
    如果你的web浏览器需要使用HTTP代理,那么你的JXTA很可能也需要代理。大多数服务器都有一个包含代理信息的首选项页面。在一些自动浏览器的代理机制中,确定是否使用了代理是很困难的。在这种情况下,要问一问本地的专家或IT部员工。
    
在Java代码行中配置HTTP代理
    如果你通过直接运行Java来启动你的程序,你可以把HTTP代理参数作为java命令行的一部分。HTTP代理通过Java系统性能定义。例如:
    % java -Dhttp.proxyHost=proxy.mycompany.com Dhttp.proxyPort=8080...
    这个设定将会配置Java使用proxy.mycompany.com为代理服务器,端口为8080。你需要使用你从web服务器模仿的值。

JXTA和代理人证
    当HTTP需要认证的时候,以下Java系统性质需要被设定:
    % java -Djxta.proxy.user=usr -Djxta.proxy.password=pwd...
    配置信息被保存在安全信息文件中(用户名和密码),存储位置./.cache/example_name/PlatfornConfig;(./.cache/example_name/cm)。程序下次运行的时候,这些信息被用来配置你的节点。
    java -DJXTA_HOME="alternate dir" ...

创建多种ID
    节点、节点组、管道和其它的JXTA资源需要被唯一的标识出来。一个JXTA ID唯一的标识了一个资源和服务。当前有六种JXTA实体定义了JXTA  ID:节点、节点组、管道、内容、模块类和模块规范。URNs被用来描述JXTA IDs。URNs是一种URI的格式“... are intended to serve as persistent, location-independent, resource identifiers”。就像是其它的URI结构,JXTA使用字符串来提供。
    一个JXTA节点ID的例子:
    urn:jxta:uuid-59616261646162614A78746150325033F3BC76FF13C2414CBC0AB663666DA53903
    一个JXTA管道的例子:
    urn:jxta:uuid-59616261646162614E504720503250338E3E786229EA460DADC1A176B69B731504
    每一个JXTA ID都有一个ID格式。这个格式描述了ID怎样被创建和怎样被程序操作。(后边这一段与前边重复了,怎么这么罗嗦……)
    下边的例子阐述了各种类型的JXTA表示是怎么构建的:
ID教程源码:
  1. package tutorial.id;
  2. import net.jxta.id.IDFactory;
  3. import net.jxta.peer.PeerID;
  4. import net.jxta.peergroup.PeerGroupID;
  5. import net.jxta.pipe.PipeID;
  6. import java.io.UnsupportedEncodingException;
  7. import java.security.MessageDigest;
  8. import java.security.NoSuchAlgorithmException;
  9. import java.text.MessageFormat;
  10. /**
  11.  * A simple and re-usable example of creating various JXTA IDs
  12.  *


  13.  * This is a two part tutorial :
  14.  *

    1.  *
    2. Illustrates the creation of predictable ID's based upon the hash of a
    3.  * provided string. This method provides an independent and deterministic
    4.  * method for generating IDs. However using this method does require care
    5.  * in the choice of the seed expression in order to prevent ID collisions
    6.  * (duplicate IDs).

    7.  *


    8.  *
    9. New random ID's encoded with a specific GroupID.

    10.  *

  15.  */
  16. public class IDTutorial {
  17.     private static final String SEED = "IDTuorial";
  18.     /**
  19.      * Returns a SHA1 hash of string.
  20.      *
  21.      * @param expression to hash
  22.      * @return a SHA1 hash of string or {@code null} if the expression could
  23.      * not be hashed.
  24.      */
  25.     private static byte[] hash(final String expression) {
  26.         byte[] result;
  27.         MessageDigest digest;
  28.         if (expression == null) {
  29.             throw new IllegalArgumentException("Invalid null expression");
  30.         }
  31.         try {
  32.             digest = MessageDigest.getInstance("SHA1");
  33.         } catch (NoSuchAlgorithmException failed) {
  34.             failed.printStackTrace(System.err);
  35.             RuntimeException failure = new IllegalStateException("Could not get
  36. SHA-1 Message");
  37.             failure.initCause(failed);
  38.             throw failure;
  39.         }
  40.         try {
  41.  byte[] expressionBytes = expression.getBytes("UTF-8");
  42.             result = digest.digest(expressionBytes);
  43.         } catch (UnsupportedEncodingException impossible) {
  44.             RuntimeException failure =
  45.                   new IllegalStateException("Could not encode expression as UTF8");
  46.             failure.initCause(impossible);
  47.             throw failure;
  48.         }
  49.         return result;
  50.     }
  51.     /**
  52.      * Given a pipe name, it returns a PipeID who's value is chosen based upon that name.
  53.      *
  54.      * @param pipeName instance name
  55.      * @param pgID the group ID encoding
  56.      * @return The pipeID value
  57.      */
  58.     public static PipeID createPipeID(PeerGroupID pgID, String pipeName) {
  59.         String seed = pipeName + SEED;
  60.         return IDFactory.newPipeID(pgID, hash(seed.toLowerCase()));
  61.     }
  62.     /**
  63.      * Creates group encoded random PipeID.
  64.      *
  65.      * @param pgID the group ID encoding
  66.      * @return The pipeID value
  67.      */
  68.     public static PipeID createNewPipeID(PeerGroupID pgID) {
  69.         return IDFactory.newPipeID(pgID);
  70.     }
  71.     /**
  72.      * Creates group encoded random PeerID.
  73.      *
  74.      * @param pgID the group ID encoding
  75.      * @return The PeerID value
  76.      */
  77.     public static PeerID createNewPeerID(PeerGroupID pgID) {
  78.         return IDFactory.newPeerID(pgID);
  79.     }
  80.     /**
  81.      * Given a peer name generates a Peer ID who's value is chosen based upon that name.
  82.      *
  83.      * @param peerName instance name
  84.      * @param pgID the group ID encoding
  85.      * @return The PeerID value
  86.      */
  87.     public static PeerID createPeerID(PeerGroupID pgID, String peerName) {
  88.         String seed = peerName + SEED;
  89.         return IDFactory.newPeerID(pgID, hash(seed.toLowerCase()));
  90.     }
  91.     /**
  92.      * Creates group encoded random PeerGroupID.
  93. *
  94.      * @param pgID the group ID encoding
  95.      * @return The PeerGroupID value
  96.      */
  97.     public static PeerGroupID createNewPeerGroupID(PeerGroupID pgID) {
  98.         return IDFactory.newPeerGroupID(pgID);
  99.     }
  100.     /**
  101.      * Given a group name generates a Peer Group ID who's value is chosen based
  102.      * upon that name.
  103.      *
  104.      * @param groupName group name encoding value
  105.      * @return The PeerGroupID value
  106.      */
  107.     public static PeerGroupID createPeerGroupID(final String groupName) {
  108.         //Use lower case to avoid any locale conversion inconsistencies
  109.         return IDFactory.newPeerGroupID(PeerGroupID.defaultNetPeerGroupID,
  110.                                              hash(SEED + groupName.toLowerCase()));
  111.     }
  112.     /**
  113.      * Contructs and returns an string encoded Infrastructure PeerGroupID.
  114.      *
  115.      * @param groupName the string encoding
  116.      * @return The infraPeerGroupID PeerGroupID
  117.      */
  118.     public static PeerGroupID createInfraPeerGroupID(String groupName) {
  119.         return createPeerGroupID(groupName);
  120.     }
  121.     /**
  122.      * Main method
  123.      *
  124.      * @param args command line arguments. None defined
  125.      */
  126.     public static void main(String args[]) {
  127.         PeerGroupID infra = createInfraPeerGroupID("infra");
  128.         PeerID peerID = createPeerID(infra, "peer");
  129.         PipeID pipeID = createPipeID(PeerGroupID.defaultNetPeerGroupID, "pipe");
  130.         System.out.println(MessageFormat.format(
  131.                        "\n\nAn infrastucture PeerGroupID: {0}", infra.toString()));
  132.         System.out.println(MessageFormat.format(
  133.                "PeerID with the above infra ID encoding: {0}", peerID.toString()));
  134.         System.out.println(MessageFormat.format("PipeID with the default
  135. defaultNetPeerGroupID encoding: {0}", pipeID.toString()));
  136.         peerID = createNewPeerID(PeerGroupID.defaultNetPeerGroupID);
  137.         pipeID = createNewPipeID(PeerGroupID.defaultNetPeerGroupID);
  138.         PeerGroupID pgid = createNewPeerGroupID(PeerGroupID.defaultNetPeerGroupID);
  139.         System.out.println(
  140.           MessageFormat.format("\n\nNew PeerID created : {0}", peerID.toString()));
  141.         System.out.println(
  142.               MessageFormat.format("New PipeID created : {0}", pipeID.toString()));
  143.         System.out.println(
  144. MessageFormat.format("New PeerGroupID created : {0}", pgid.toString()));
  145.     }
  146. }

广告
    广告是JXTA项目的核心内容,它用来广告节点、节点组、服务、管道和其它的JXTA资源。广告为JXTA资源提供了一种平***立地表示,使得两个不同的平台实现之间可以交换信息(Java、C等)。
    每一个广告都带有一个可以描述此广告的文档。广告通常被描述为XML文档。方法Advertisement.getDocument(MimeMediaType)用来生成广告的描述。不同的描述通过mime类型的选择后是有效的。典型的mime类型是“text/xml”或“text/plain”,它们能够生成广告的文本表示。使用AdvertisementFactory构造广告实例比使用Advertisement类构造广告实例更常用。所有的在net.jxta.protocol中定义的公共广告都是抽象类。对于每一个抽象公共广告,它们都有一个包含文档创建和解析方法的私有实现。私有的实现使用AdvertisementFactory注册。新的广告类型必须用下边阐述所示的方式进行注册或者是使用META-INF/services/net.jxta.document.Advertisement扩展。
    下边的实例阐述了新的广告类型的创建方法,还有通过广告工厂对其进行注册的方法:
     AdvertisementFactory.registerAdvertisementInstance(
      AdvertisementTutorial.getAdvertisementType(),new AdvertisementTutorial.Instantiator());

广告教程代码
  1. package tutorial.advertisement;
  2. import net.jxta.document.*;
  3. import net.jxta.id.ID;
  4. import net.jxta.id.IDFactory;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.Serializable;
  8. import java.net.InetAddress;
  9. import java.net.URI;
  10. import java.net.URISyntaxException;
  11. import java.net.UnknownHostException;
  12. import java.util.Enumeration;
  13. import java.util.logging.Logger;
  14. /**
  15.  * Simple Advertisement Tutorial creates a advertisment describing a system
  16.  *


  17.  *

  18.  * <?xml version="1.0"?>
  19.  * <!DOCTYPE jxta:System>
  20.  * <jxta:System xmlns:jxta="">
  21.  * <id>id</id>
  22.  * <name>Device Name</name>
  23.  * <ip>ip address</ip>
  24.  * <hwarch>x86</hwarch>
  25.  * <hwvendor>Sun MicroSystems</hwvendor>
  26.  * <OSName></OSName>
  27.  * <OSVer></OSVer>
  28.  * <osarch></osarch>
  29.  * <sw></sw>
  30.  * </jxta:System>
  31.  *
  32.  */
  33. public class AdvertisementTutorial extends Advertisement
  34.         implements Comparable, Cloneable, Serializable {
  35.     private String hwarch;
  36.     private String hwvendor;
  37.     private ID id = ID.nullID;
  38.     private String ip;
  39.     private String name;
  40.     private String osname;
  41.     private String osversion;
  42.     private String osarch;
  43.     private String inventory;
  44.     private final static Logger LOG =
  45.             Logger.getLogger(AdvertisementTutorial.class.getName());
  46.     private final static String OSNameTag = "OSName";
  47.     private final static String OSVersionTag = "OSVer";
  48.     private final static String OSarchTag = "osarch";
  49.     private final static String hwarchTag = "hwarch";
  50.     private final static String hwvendorTag = "hwvendor";
  51.     private final static String idTag = "ID";
  52.  private final static String ipTag = "ip";
  53.     private final static String nameTag = "name";
  54.     private final static String swTag = "sw";
  55.     /**
  56.      * Indexable fields. Advertisements must define the indexables, in order
  57.      * to properly index and retrieve these advertisements locally and on the
  58.      * network
  59.      */
  60.     private final static String[] fields = {idTag, nameTag, hwarchTag};
  61.     /**
  62.      * Default Constructor
  63.      */
  64.     public AdvertisementTutorial() {
  65.     }
  66.     /**
  67.      * Construct from a StructuredDocument
  68.      *
  69.      * @param root Root element
  70.      */
  71.     public AdvertisementTutorial(Element root) {
  72.         TextElement doc = (TextElement) root;
  73.         if (!getAdvertisementType().equals(doc.getName())) {
  74.             throw new IllegalArgumentException("Could not construct : " +
  75.                     getClass().getName() + "from doc containing a " +
  76. doc.getName());
  77.         }
  78.         initialize(doc);
  79.     }
  80.     /**
  81.      * Construct a doc from InputStream
  82.      *
  83.      * @param stream the underlying input stream.
  84.      * @throws IOException if an I/O error occurs.
  85.      */
  86.     public AdvertisementTutorial(InputStream stream) throws IOException {
  87.         StructuredTextDocument doc = (StructuredTextDocument)
  88.                 StructuredDocumentFactory
  89.                         .newStructuredDocument(MimeMediaType.XMLUTF8, stream);
  90.         initialize(doc);
  91.     }
  92.     /**
  93.      * Sets the hWArch attribute of the AdvertisementTutorial object
  94.      *
  95.      * @param hwarch The new hWArch value
  96.      */
  97.     public void setHWArch(String hwarch) {
  98.         this.hwarch = hwarch;
  99.     }
  100.     /**
  101.      * Sets the OSArch attribute of the AdvertisementTutorial object
  102. *
  103.      * @param osarch The new hWArch value
  104.      */
  105.     public void setOSArch(String osarch) {
  106.         this.osarch = osarch;
  107.     }
  108.     /**
  109.      * Sets the hWVendor attribute of the AdvertisementTutorial object
  110.      *
  111.      * @param hwvendor The new hWVendor value
  112.      */
  113.     public void setHWVendor(String hwvendor) {
  114.         this.hwvendor = hwvendor;
  115.     }
  116.     /**
  117.      * sets the unique id
  118.      *
  119.      * @param id The id
  120.      */
  121.     public void setID(ID id) {
  122.         this.id = (id == null ? null : id);
  123.     }
  124.     /**
  125.      * Sets the iP attribute of the AdvertisementTutorial object
  126.      *
  127.      * @param ip The new iP value
  128.      */
  129.     public void setIP(String ip) {
  130.         this.ip = ip;
  131.     }
  132.     /**
  133.      * Sets the name attribute of the AdvertisementTutorial object
  134.      *
  135.      * @param name The new name value
  136.      */
  137.     public void setName(String name) {
  138.         this.name = name;
  139.     }
  140.     /**
  141.      * Sets the oSName attribute of the AdvertisementTutorial object
  142.      *
  143.      * @param osname The new oSName value
  144.      */
  145.     public void setOSName(String osname) {
  146.         this.osname = osname;
  147.     }
  148.     /**
  149.      * Sets the oSVersion attribute of the AdvertisementTutorial object
  150.      *
  151.      * @param osversion The new oSVersion value
  152.      */
  153.  public void setOSVersion(String osversion) {
  154.         this.osversion = osversion;
  155.     }
  156.     /**
  157.      * Sets the SWInventory attribute of the AdvertisementTutorial object
  158.      *
  159.      * @param inventory the software inventory of the system
  160.      */
  161.     public void setSWInventory(String inventory) {
  162.         this.inventory = inventory;
  163.     }
  164.     /**
  165.      * {@inheritDoc}
  166.      *
  167.      * @param asMimeType Document encoding
  168.      * @return The document value
  169.      */
  170.     @Override
  171.     public Document getDocument(MimeMediaType asMimeType) {
  172.         StructuredDocument adv =
  173. StructuredDocumentFactory.newStructuredDocument(asMimeType,
  174.                 getAdvertisementType());
  175.         if (adv instanceof Attributable) {
  176.             ((Attributable) adv).addAttribute("xmlns:jxta", "");
  177.         }
  178.         Element e;
  179.         e = adv.createElement(idTag, getID().toString());
  180.         adv.appendChild(e);
  181.         e = adv.createElement(nameTag, getName().trim());
  182.         adv.appendChild(e);
  183.         e = adv.createElement(OSNameTag, getOSName().trim());
  184.         adv.appendChild(e);
  185.         e = adv.createElement(OSVersionTag, getOSVersion().trim());
  186.         adv.appendChild(e);
  187.         e = adv.createElement(OSarchTag, getOSArch().trim());
  188.         adv.appendChild(e);
  189.         e = adv.createElement(ipTag, getIP().trim());
  190.         adv.appendChild(e);
  191.         e = adv.createElement(hwarchTag, getHWArch().trim());
  192.         adv.appendChild(e);
  193.         e = adv.createElement(hwvendorTag, getHWVendor().trim());
  194.         adv.appendChild(e);
  195.         e = adv.createElement(swTag, getSWInventory().trim());
  196.         adv.appendChild(e);
  197.         return adv;
  198.     }
  199.     /**
  200.      * Gets the hWArch attribute of the AdvertisementTutorial object
  201.      *
  202.      * @return The hWArch value
  203.      */
  204.     public String getHWArch() {
  205.         return hwarch;
  206.     }
  207.  /**
  208.      * Gets the OSArch attribute of the AdvertisementTutorial object
  209.      *
  210.      * @return The OSArch value
  211.      */
  212.     public String getOSArch() {
  213.         return osarch;
  214.     }
  215.     /**
  216.      * Gets the hWVendor attribute of the AdvertisementTutorial object
  217.      *
  218.      * @return The hWVendor value
  219.      */
  220.     public String getHWVendor() {
  221.         return hwvendor;
  222.     }
  223.     /**
  224.      * returns the id of the device
  225.      *
  226.      * @return ID the device id
  227.      */
  228.     @Override
  229.     public ID getID() {
  230.         return (id == null ? null : id);
  231.     }
  232.     /**
  233.      * Gets the IP attribute of the AdvertisementTutorial object
  234.      *
  235.      * @return The IP value
  236.      */
  237.     public String getIP() {
  238.         return ip;
  239.     }
  240.     /**
  241.      * Gets the name attribute of the AdvertisementTutorial object
  242.      *
  243.      * @return The name value
  244.      */
  245.     public String getName() {
  246.         return name;
  247.     }
  248.     /**
  249.      * Gets the OSName attribute of the AdvertisementTutorial object
  250.      *
  251.      * @return The OSName value
  252.      */
  253.     public String getOSName() {
  254.         return osname;
  255.     }
  256.     /**
  257. * Gets the Software Inventory text element
  258.      *
  259.      * @return The Inventory value
  260.      */
  261.     public String getSWInventory() {
  262.         if (inventory == null) {
  263.             inventory = "";
  264.         }
  265.         return inventory;
  266.     }
  267.     /**
  268.      * Gets the OSVersion attribute of the AdvertisementTutorial object
  269.      *
  270.      * @return The OSVersion value
  271.      */
  272.     public String getOSVersion() {
  273.         return osversion;
  274.     }
  275.     /**
  276.      * Process an individual element from the document.
  277.      *
  278.      * @param elem the element to be processed.
  279.      * @return true if the element was recognized, otherwise false.
  280.      */
  281.     protected boolean handleElement(TextElement elem) {
  282.         if (elem.getName().equals(idTag)) {
  283.             try {
  284.                 URI id = new URI(elem.getTextValue());
  285.                 setID(IDFactory.fromURI(id));
  286.             } catch (URISyntaxException badID) {
  287.                 throw new IllegalArgumentException("unknown ID format in
  288. advertisement: " +
  289.                         elem.getTextValue());
  290.             }
  291.             catch (ClassCastException badID) {
  292.                 throw new IllegalArgumentException("Id is not a known id type: " +
  293.                         elem.getTextValue());
  294.             }
  295.             return true;
  296.         }
  297.         if (elem.getName().equals(nameTag)) {
  298.             setName(elem.getTextValue());
  299.             return true;
  300.         }
  301.         if (elem.getName().equals(OSNameTag)) {
  302.             setOSName(elem.getTextValue());
  303.             return true;
  304.         }
  305.         if (elem.getName().equals(OSVersionTag)) {
  306.             setOSVersion(elem.getTextValue());
  307.             return true;
  308.         }
  309.         if (elem.getName().equals(OSarchTag)) {
  310.             setOSArch(elem.getTextValue());
  311.             return true;
  312. }
  313.         if (elem.getName().equals(ipTag)) {
  314.             setIP(elem.getTextValue());
  315.             return true;
  316.         }
  317.         if (elem.getName().equals(hwarchTag)) {
  318.             setHWArch(elem.getTextValue());
  319.             return true;
  320.         }
  321.         if (elem.getName().equals(hwvendorTag)) {
  322.             setHWVendor(elem.getTextValue());
  323.             return true;
  324.         }
  325.         if (elem.getName().equals(swTag)) {
  326.             setSWInventory(elem.getTextValue());
  327.             return true;
  328.         }
  329.         // element was not handled
  330.         return false;
  331.     }
  332.     /**
  333.      * Intialize a System advertisement from a portion of a structured document.
  334.      *
  335.      * @param root document root
  336.      */
  337.     protected void initialize(Element root) {
  338.         if (!TextElement.class.isInstance(root)) {
  339.             throw new IllegalArgumentException(getClass().getName() +
  340.                     " only supports TextElement");
  341.         }
  342.         TextElement doc = (TextElement) root;
  343.         if (!doc.getName().equals(getAdvertisementType())) {
  344.             throw new IllegalArgumentException("Could not construct : "
  345.                     + getClass().getName() + "from doc containing a " +
  346.                     doc.getName());
  347.         }
  348.         Enumeration elements = doc.getChildren();
  349.         while (elements.hasMoreElements()) {
  350.             TextElement elem = (TextElement) elements.nextElement();
  351.             if (!handleElement(elem)) {
  352.                 LOG.warning("Unhandleded element \'" + elem.getName() + "\' in " +
  353.                         doc.getName());
  354.             }
  355.         }
  356.     }
  357.     /**
  358.      * {@inheritDoc}
  359.      */
  360.     @Override
  361.     public final String[] getIndexFields() {
  362.         return fields;
  363.     }
  364.     /**
  365.      * {@inheritDoc}
  366.  */
  367.     @Override
  368.     public boolean equals(Object obj) {
  369.         if (this == obj) {
  370.             return true;
  371.         }
  372.         if (obj instanceof AdvertisementTutorial) {
  373.             AdvertisementTutorial adv = (AdvertisementTutorial) obj;
  374.             return getID().equals(adv.getID());
  375.         }
  376.         return false;
  377.     }
  378.     /**
  379.      * {@inheritDoc}
  380.      */
  381.     public int compareTo(Object other) {
  382.         return getID().toString().compareTo(other.toString());
  383.     }
  384.     /**
  385.      * All messages have a type (in xml this is !doctype) which
  386.      * identifies the message
  387.      *
  388.      * @return String "jxta:AdvertisementTutorial"
  389.      */
  390.     public static String getAdvertisementType() {
  391.         return "jxta:AdvertisementTutorial";
  392.     }
  393.     /**
  394.      * Instantiator
  395.      */
  396.     public static class Instantiator implements AdvertisementFactory.Instantiator {
  397.         /**
  398.          * Returns the identifying type of this Advertisement.
  399.          *
  400.          * @return String the type of advertisement
  401.          */
  402.         public String getAdvertisementType() {
  403.             return AdvertisementTutorial.getAdvertisementType();
  404.         }
  405.         /**
  406.          * Constructs an instance of Advertisement matching the
  407.          * type specified by the advertisementType parameter.
  408.          *
  409.          * @return The instance of Advertisement or null if it
  410.          * could not be created.
  411.          */
  412.         public Advertisement newInstance() {
  413.             return new AdvertisementTutorial();
  414.         }
  415.         /**
  416.          * Constructs an instance of Advertisement matching the
  417. * type specified by the advertisementType parameter.
  418.          *
  419.          * @param root Specifies a portion of a StructuredDocument which will
  420.          * be converted into an Advertisement.
  421.          * @return The instance of Advertisement or null if it
  422.          * could not be created.
  423.          */
  424.         public Advertisement newInstance(net.jxta.document.Element root) {
  425.             return new AdvertisementTutorial(root);
  426.         }
  427.     }
  428.     /**
  429.      * Main method
  430.      *
  431.      * @param args command line arguments. None defined
  432.      */
  433.     public static void main(String args[]) {
  434.         // The following step is required and only need to be done once,
  435.         // without this step the AdvertisementFactory has no means of
  436.         // associating an advertisement name space with the proper obect
  437.         // in this cast the AdvertisementTutorial
  438.         AdvertisementFactory.registerAdvertisementInstance(
  439.                 AdvertisementTutorial.getAdvertisementType(),
  440.                 new AdvertisementTutorial.Instantiator());
  441.         AdvertisementTutorial advTutorial = new AdvertisementTutorial();
  442.         advTutorial.setID(ID.nullID);
  443.         advTutorial.setName("AdvertisementTutorial");
  444.         try {
  445.             advTutorial.setIP(InetAddress.getLocalHost().getHostAddress());
  446.         } catch (UnknownHostException ignored) {
  447.             //ignored
  448.         }
  449.         advTutorial.setOSName(System.getProperty("os.name"));
  450.         advTutorial.setOSVersion(System.getProperty("os.version"));
  451.         advTutorial.setOSArch(System.getProperty("os.arch"));
  452.         advTutorial.setHWArch(System.getProperty("HOSTTYPE",
  453.                 System.getProperty("os.arch")));
  454.         advTutorial.setHWVendor(System.getProperty("java.vm.vendor"));
  455.         System.out.println(advTutorial.toString());
  456.     }
  457. }

信息和信息元素
    一个JXTA信息是一个协议信息和内容的容器。每一个信息都由一系列的信息元素组成。信息元素包含信息的协议信息和内容。每一个元素都包含信息的一部分。元素的目标和内容是由信息协议定义所定义的。按照信息协议,信息元素可以包含所需的多种类型的数据。
    JXTA信息包含一个含有0个或多个信息元素的有序列表。相同的信息元素可能会随时出现在信息中。信息中的每一个信息元素都与一个名字空间相联系。名字空间允许在一个信息中使用多个协议层,而避免了它们信息元素的冲突。例如,所有的JXTA核心协议都把它们的信息存储到保留的名字空间‘jxta’中。默认的命名空间对程序和服务来说是保留的。应用总会为它们的信息元素定义自己的命名空间,但是要避免使用‘jxta’和在模块规则ID中定义的命名空间,除了它们自己的MSID。
    一个JXTA信息元素可以用来存储多种类型的数据。JXTA JSE API支持多种信息元素,而附加的信息类型可能被定义。所提供的元素类允许你从一个字符串、字节数组、文档、输入流等创建信息元素。为了将数据作为信息的一部分传输,则元素的数据在发送之前必须被分成原始的字节流。有多种信息元素的“调料”用来方便而有效地进行原始比特的转换。所有的元素类只是将元素数据转换为二进制数据的简单代理。
    在使用信息元素的开发中,你不用在创建之后考虑信息元素的原始类型。比起StringMessageElement elem = new StringMessageElement("foo","bar",null);我们更常使用MessageElement elem = new StringMessageElement("foo","bar",null);。通过使用MessageElement类加强每一个信息元素的通用性——所有的数据都以字节的形式发送和接受。每一个信息元素都分为四部分:
  1. 一个可选的名字可以是任何字符串。没有命名的元素假定有“”的名字(空字符串)。
  2. 一个可选的MIME媒体类型。如果没有指定类型,MIME媒体类型会被假设为“Applacation/Octet-Stream”,二进制数据的默认类型。
  3. 信息元素的内容,一个字节序列。为了能将信息元素的内容作为信息的一部分进行传输,信息元素必须在发送前被分成原始字节。信息元素可以从各种各样的数据类型转化而来,其中有字符串、字节数组、文档、二进制数据等。在各种情况下,不管数据的数据源,结果信息元素都是一个数组队列的容器。所有信息元素都会以原始比特的方式进行发送和接受。 有多种信息元素的“调料”用来方便而有效地进行原始比特的转换。
  4. 一个可选的签名:每个信息元素都可以与一个额外的信息元素相联系,这个元素中可能包含经过加密的这个元素的签名或哈希值。
为JXTA信息设计节点
  • 每一个信息元素你大约会加入50个字节的传输开销。如果可能,避免协议设计使用太多的小元素。
  • 命名空间只与将信息元素作为元素加入一个信息有联系。命名空间在信息中动态的与信息元素相关联,因为对于元素来说适当的命名空间往往是基于上下文发生改变的。
  • 有四种简单的方法让程序和服务使用信息命名空间:
    • 只是用默认的命名空间。因为这个命名空间是为要创建信息的程序和服务保留的,所以它是最容易,也是最通常的选择。
    • 使用一个习惯性的硬编码命名空间,如“myApplication”。这种方法在JXTA程序中是很常用的,它使得程序可以按照需求定义尽可能多的命名空间。尽管不太可能,当使用硬编码命名空间是有一个小问题,就是两个单独的编码之间可能会有冲突。如果方便的话,程序和服务需要使用它们的MSID代替它们的命名空间。
    • 它们的MSID是它们常用的命名空间。基于MSID的命名空间是为那些实现了某些模块规范的程序和服务而预定义的。例如,标准JXTA集合节点服务的MSID是urn:jxta:uuid-deadbeefdeafbabafeedbabe000000060106.则命名空间 urn:jxta:uuid-deadbeefdeafbabafeedbabe000000060106.可能只会被实现了相应规范的JXTA集合节点所使用。
    • 使用一个唯一的随即命名空间。MessageElement类为创建的基于UUIDs的唯一的随即名字提供了工具。这些随机的名字可以用于程序和服务的单一信息或序列信息。程序也可以产生它们自己的随即命名空间的名字,只要所选的名字是唯一的。通常这意味着要使用UUIDs或安全信息摘要(SHA1、MD5等)作为命名空间的名字。
  • 信息可以被重用或非常方便的克隆。在许多程序中,在信息发送前创建一个预定义的、可被克隆的信息模板比每次都直接创建一个新的信息要更方便。
  • 来自一个单一线程的信息并不是同步的,而且只能可靠的使用。这在信息发送的时候经常被套用。直到信息发送成功它都不会被其它程序使用。

为信息元素设计节点
  • 信息元素是不变的,同时它作为信息的一部分被重复使用。这个特点常常用在不变的值,例如地址数据,或者是缓存的信息,例如节点广告。
  • 包含在MessageElement中的数据有四种方法访问:
    • 作为一个 java.io.InputStream
    • 发数据发给一个 java.io.OutputStream
    • 作为一个 java.lang.String
    • 作为一个字节数组

信息和信息元素教程源码
  1. package tutorial.message;
  2. import net.jxta.document.AdvertisementFactory;
  3. import net.jxta.document.MimeMediaType;
  4. import net.jxta.document.StructuredDocumentFactory;
  5. import net.jxta.document.XMLDocument;
  6. import net.jxta.endpoint.ByteArrayMessageElement;
  7. import net.jxta.endpoint.Message;
  8. import net.jxta.endpoint.Message.ElementIterator;
  9. import net.jxta.endpoint.MessageElement;
  10. import net.jxta.endpoint.StringMessageElement;
  11. import net.jxta.endpoint.TextDocumentMessageElement;
  12. import net.jxta.endpoint.WireFormatMessage;
  13. import net.jxta.endpoint.WireFormatMessageFactory;
  14. import net.jxta.id.IDFactory;
  15. import net.jxta.peergroup.PeerGroupID;
  16. import net.jxta.pipe.PipeService;
  17. import net.jxta.protocol.PipeAdvertisement;
  18. import java.io.ByteArrayOutputStream;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.io.ObjectInputStream;
  23. import java.io.ObjectOutputStream;
  24. import java.io.RandomAccessFile;
  25. import java.util.zip.GZIPInputStream;
  26. import java.util.zip.GZIPOutputStream;
  27. /**
  28. * A simple and re-usable example of manipulating JXATA Messages. Included in
  29. * this tutorial are:
  30. *

  31. *
    • *
    • Adding and reading {@code String}, {@code int} and {@code long} with Message elements
    • *
    • Adding and reading Java {@code Object} with Message Elements.
    • *
    • Adding and reading byte arrays with Message Elements.
    • *
    • Adding and reading JXTA Advertisements with Message Elements.
    • *
    • Compressing message element content with gzip.
    • *
  32. */
  33. public class MessageTutorial {
  34. private final static MimeMediaType GZIP_MEDIA_TYPE =
  35. new MimeMediaType("application/gzip").intern();
  36. /**
  37. * Adds a String to a Message as a StringMessageElement
  38. *
  39. * @param message The message to add to
  40. * @param nameSpace The namespace of the element to add. a null value assumes
  41. default namespace.
  42. * @param elemName Name of the Element.
  43. * @param string The string to add
  44. */
  45. public static void addStringToMessage(Message message,
  46. String nameSpace, String elemName, String string) {
  47. message.addMessageElement(nameSpace,
  48. new StringMessageElement(elemName,
  49. string,
  50. null));
  51. }
  52. /**
  53. * Adds a long to a message
  54. *
  55. * @param message The message to add to
  56. * @param nameSpace The namespace of the element to add. a null value assumes
  57. default namespace.
  58. * @param elemName Name of the Element.
  59. * @param data The feature to be added to the LongToMessage attribute
  60. */
  61. public static void addLongToMessage(Message message,
  62. String nameSpace, String elemName, long data) {
  63. message.addMessageElement(nameSpace,
  64. new StringMessageElement(elemName,
  65. Long.toString(data),
  66. null));
  67. }
  68. /**
  69. * Adds a int to a message
  70. *
  71. * @param message The message to add to
  72. * @param nameSpace The namespace of the element to add. a null value assumes
  73. default namespace.
  74. * @param elemName Name of the Element.
  75. * @param data The feature to be added to the IntegerToMessage attribute
  76. */
  77. public static void addIntegerToMessage(Message message, String nameSpace,
  78. String elemName, int data) {
  79. message.addMessageElement(nameSpace,
  80. new StringMessageElement(elemName,
  81. Integer.toString(data),
  82. null));
  83. }
  84. /**
  85. * Adds an byte array to a message
  86. *
  87. * @param message The message to add to
  88. * @param nameSpace The namespace of the element to add. a null value assumes
  89. default namespace.
  90. * @param elemName Name of the Element.
  91. * @param data the byte array
  92. * @param compress indicates whether to use GZIP compression
  93. * @throws IOException if an io error occurs
  94. */
  95. public static void addByteArrayToMessage(Message message, String nameSpace,
  96. String elemName, byte[] data, boolean compress) throws IOException {
  97. byte[] buffer = data;
  98. MimeMediaType mimeType = MimeMediaType.AOS;
  99. if (compress) {
  100. ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  101. GZIPOutputStream gos = new GZIPOutputStream(outStream);
  102. gos.write(data, 0, data.length);
  103. gos.finish();
  104. gos.close();
  105. buffer = outStream.toByteArray();
  106. mimeType = GZIP_MEDIA_TYPE;
  107. }
  108. message.addMessageElement(nameSpace,
  109. new ByteArrayMessageElement(elemName,
  110. mimeType,
  111. buffer,
  112. null));
  113. }
  114. /**
  115. * Adds an Object to message within the specified name space and with the
  116. specified element name
  117. * @param message the message to add the object to
  118. * @param nameSpace the name space to add the object under
  119. * @param elemName the given element name
  120. * @param object the object
  121. * @throws IOException if an io error occurs
  122. */
  123. public static void addObjectToMessage(Message message, String nameSpace,
  124. String elemName, Object object) throws IOException {
  125. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  126. ObjectOutputStream oos = new ObjectOutputStream(bos);
  127. oos.writeObject(object);
  128. oos.close();
  129. bos.close();
  130. addByteArrayToMessage(message, nameSpace, elemName, bos.toByteArray(), false);
  131. }
  132. /**
  133. * Returns a String from a message
  134. *
  135. * @param message The message to retrieve from
  136. * @param nameSpace The namespace of the element to get.
  137. * @param elemName Name of the Element.
  138. * @return The string value or {@code null} if there was no element matching
  139. the specified name.
  140. */
  141. public static String getStringFromMessage(Message message,
  142. String nameSpace, String elemName) {
  143. MessageElement me = message.getMessageElement(nameSpace, elemName);
  144. if (null != me) {
  145. return me.toString();
  146. } else {
  147. return null;
  148. }
  149. }
  150. /**
  151. * Returns an long from a message
  152. *
  153. * @param message The message to retrieve from
  154. * @param nameSpace The namespace of the element to get.
  155. * @param elemName Name of the Element.
  156. * @return The long value
  157. * @throws NumberFormatException If the String does not contain a parsable int.
  158. */
  159. public static long getLongFromMessage(Message message,
  160. String nameSpace, String elemName) throws NumberFormatException {
  161. String longStr = getStringFromMessage(message, nameSpace, elemName);
  162. if (null != longStr) {
  163. return Long.parseLong(longStr);
  164. } else {
  165. throw new NumberFormatException("No such Message Element.");
  166. }
  167. }
  168. /**
  169. * Returns an int from a message
  170. *
  171. * @param message The message to retrieve from
  172. * @param nameSpace The namespace of the element to get.
  173. * @param elemName Name of the Element.
  174. * @return The int value
  175. * @throws NumberFormatException If the String does not contain a parsable long.
  176. */
  177. public static int getIntegerFromMessage(Message message, String nameSpace,
  178. String elemName) throws NumberFormatException {
  179. String intStr = getStringFromMessage(message, nameSpace, elemName);
  180. if (null != intStr) {
  181. return Integer.parseInt(intStr);
  182. } else {
  183. throw new NumberFormatException("No such Message Element.");
  184. }
  185. }
  186. /**
  187. * Returns an InputStream for a byte array
  188. *
  189. * @param message The message to retrieve from
  190. * @param nameSpace The namespace of the element to get.
  191. * @param elemName Name of the Element.
  192. * @return The {@code InputStream} or {@code null} if the message has no such
  193. element, String elemName) throws IOException {
  194. * @throws IOException if an io error occurs
  195. */
  196. public static InputStream getInputStreamFromMessage(Message message,
  197. String nameSpace, String elemName) throws IOException {
  198. InputStream result = null;
  199. MessageElement element = message.getMessageElement(nameSpace, elemName);
  200. if (null == element) {
  201. return null;
  202. }
  203. if (element.getMimeType().equals(GZIP_MEDIA_TYPE)) {
  204. result = new GZIPInputStream(element.getStream());
  205. } else if (element.getMimeType().equals(MimeMediaType.AOS)) {
  206. result = element.getStream();
  207. }
  208. return result;
  209. }
  210. /**
  211. * Reads a single Java Object from a Message.
  212. *
  213. * @param message The message containing the object.
  214. * @param nameSpace The name space of the element containing the object.
  215. * @param elemName The name of the element containing the object.
  216. * @return The Object or {@code null} if the Message contained no such element.
  217. * @throws IOException if an io error occurs
  218. * @throws ClassNotFoundException if an object could not constructed from the message
  219. element
  220. */
  221. public static Object getObjectFromMessage(Message message, String nameSpace,
  222. String elemName) throws IOException, ClassNotFoundException {
  223. InputStream is = getInputStreamFromMessage(message, nameSpace, elemName);
  224. if (null == is) {
  225. return null;
  226. }
  227. ObjectInputStream ois = new ObjectInputStream(is);
  228. return ois.readObject();
  229. }
  230. /**
  231. * Prints message element names and content and some stats
  232. *
  233. * @param msg message to print
  234. * @param verbose indicates whether to print elment content
  235. */
  236. public static void printMessageStats(Message msg, boolean verbose) {
  237. try {
  238. System.out.println("------------------Begin Message---------------------");
  239. WireFormatMessage serialed = WireFormatMessageFactory.toWire(
  240. msg,
  241. new MimeMediaType("application/x-jxta-msg"), null);
  242. System.out.println("Message Size :" + serialed.getByteLength());
  243. ElementIterator it = msg.getMessageElements();
  244. while (it.hasNext()) {
  245. MessageElement el = it.next();
  246. System.out.println("Element : " + it.getNamespace() + " :: " +
  247. el.getElementName());
  248. if (verbose) {
  249. System.out.println("[" + el + "]");
  250. }
  251. }
  252. System.out.println("-------------------End Message----------------------");
  253. } catch (Exception e) {
  254. e.printStackTrace();
  255. }
  256. }
  257. /**
  258. * Illustrates adding and retrieving a String to and from a Message
  259. */
  260. public static void stringExample() {
  261. Message message = new Message();
  262. addStringToMessage(message, "TutorialNameSpace", "String Test", "This is a test");
  263. printMessageStats(message, true);
  264. System.out.println("String Value :" +
  265. getStringFromMessage(message, "TutorialNameSpace", "String Test"));
  266. }
  267. /**
  268. * Illustrates adding and retrieving a long to and from a Message
  269. */
  270. public static void longExample() {
  271. Message message = new Message();
  272. addLongToMessage(message, "TutorialNameSpace", "long test", Long.MAX_VALUE);
  273. printMessageStats(message, true);
  274. System.out.println("long Value :" +
  275. getLongFromMessage(message, "TutorialNameSpace", "long test"));
  276. }
  277. /**
  278. * Illustrates adding and retrieving an integer to and from a Message
  279. */
  280. public static void intExample() {
  281. Message message = new Message();
  282. addIntegerToMessage(message, "TutorialNameSpace", "int test", Integer.MAX_VALUE);
  283. printMessageStats(message, true);
  284. System.out.println("int Value :" +
  285. getIntegerFromMessage(message, "TutorialNameSpace", "int test"));
  286. }
  287. /**
  288. * Illustrates adding and retrieving byte-array to and from a Message
  289. */
  290. public static void byteArrayExample() {
  291. Message message = new Message();
  292. try {
  293. File file = new File("message.tst");
  294. file.createNewFile();
  295. RandomAccessFile raf = new RandomAccessFile(file, "rw");
  296. raf.setLength(1024 * 4);
  297. int size = 4096;
  298. byte[] buf = new byte[size];
  299. raf.read(buf, 0, size);
  300. addByteArrayToMessage(message, "TutorialNameSpace", "byte test", buf, true);
  301. printMessageStats(message, true);
  302. InputStream is = getInputStreamFromMessage(message,
  303. "TutorialNameSpace", "byte test");
  304. int count = 0;
  305. while (is.read() != -1) {
  306. count++;
  307. }
  308. System.out.println("Read " + count + " byte back");
  309. } catch (IOException io) {
  310. io.printStackTrace();
  311. }
  312. }
  313. /**
  314. * Illustrates adding and retrieving advertisements to and from a Message
  315. */
  316. public static void xmlDocumentExample() {
  317. Message message = new Message();
  318. PipeAdvertisement pipeAdv = (PipeAdvertisement)
  319. AdvertisementFactory.newAdvertisement(
  320. PipeAdvertisement.getAdvertisementType());
  321. pipeAdv.setPipeID(IDFactory.newPipeID(PeerGroupID.defaultNetPeerGroupID));
  322. pipeAdv.setType(PipeService.UnicastType);
  323. message.addMessageElement("MESSAGETUT", new
  324. TextDocumentMessageElement("MESSAGETUT",
  325. (XMLDocument) pipeAdv.getDocument(MimeMediaType.XMLUTF8), null));
  326. MessageElement msgElement = message.getMessageElement("MESSAGETUT", "MESSAGETUT");
  327. try {
  328. XMLDocument asDoc = (XMLDocument)
  329. StructuredDocumentFactory.newStructuredDocument(msgElement.getMimeType(),
  330. msgElement.getStream());
  331. PipeAdvertisement newPipeAdv = (PipeAdvertisement)
  332. AdvertisementFactory.newAdvertisement(asDoc);
  333. System.out.println(newPipeAdv.toString());
  334. } catch (IOException e) {
  335. // This is thrown if the message element could not be read.
  336. e.printStackTrace();
  337. } catch (IllegalArgumentException e) {
  338. // This is thrown if the document or advertisement is invalid (illegal
  339. // values, missing tags, etc.)
  340. e.printStackTrace();
  341. }
  342. }
  343. /**
  344. * Main method
  345. *
  346. * @param args command line arguments. None defined
  347. */
  348. public static void main(String args[]) {
  349. stringExample();
  350. longExample();
  351. intExample();
  352. byteArrayExample();
  353. xmlDocumentExample();
  354. }
  355. }

上一篇:javascript完整教程 完美js从零学起!
下一篇:python学习笔记