18、JWorkPlace 应用开发全解析

JWorkPlace 应用开发全解析

在软件开发领域,JWorkPlace 应用凭借其独特的功能和架构,为用户提供了强大的服务和便捷的交互体验。本文将深入探讨 JWorkPlace 应用中的多个关键部分,包括内容空间管理、消息服务、客户端服务发现、ServiceUI 项目以及应用的运行步骤等。

内容空间管理

在 JWorkPlace 中,内容空间管理是一个重要的功能。通过 getContentSpace 方法,可以检查访客是否已有定义的内容列表,并根据需要授予文件访问权限。以下是该方法的代码实现:

public ContentMap[] getContentSpace(String user) throws RemoteException, IOException {
    List userSpaceList = (List)userMap.get(user);
    if(userSpaceList == null)
        return new ContentMap[0];
    ArrayList contentList = new ArrayList(userSpaceList);
    if(groupMap.containsKey(user)) {
        List groupContent = (List)groupMap.get(user);
        contentList.addAll(groupContent);
    }
    return (ContentMap[])contentList.toArray(new ContentMap[0]);
}

这个方法的逻辑是,首先从 userMap 中获取用户的内容空间列表。如果列表为空,则返回一个空的 ContentMap 数组。接着,将用户的内容空间列表添加到 contentList 中。如果 groupMap 中包含该用户,则将该用户所在组的内容也添加到 contentList 中。最后,将 contentList 转换为 ContentMap 数组并返回。

消息服务

消息服务是 JWorkPlace 中的一个重要组成部分,它是对第五章“JavaSpaces 服务”中开发的聊天应用的改进版本。 MessengerInterface 为 JavaSpace API 提供了简化的包装,而 MessengerService 实现了该接口。以下是 MessengerInterface 的代码:

package org.jworkplace.chat;

import java.rmi.RemoteException;
import java.rmi.MarshalledObject;
import java.io.IOException;
import net.jini.core.entry.Entry;
import net.jini.core.transaction.TransactionException;
import net.jini.core.entry.UnusableEntryException;

public interface MessengerInterface extends java.io.Serializable {
    public Entry read(Entry template) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
    public Entry readIfExists(Entry template) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
    public void write(Entry entry) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
    public void write(Entry entry, long leaseTime) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
    public Entry take(Entry entry) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
    public Entry takeIfExists(Entry entry) throws RemoteException, TransactionException, UnusableEntryException, InterruptedException;
}

在 JWorkPlace 示例应用中,通信通道与活动的内容空间名称相关联。当激活一个内容空间时,就会使用 JavaSpaces 激活一个消息通道,从而可以向共享或有权访问该空间的所有成员发送消息。此外,还有一个默认通道 WorkPlaceChannel ,可用于向所有工作场所成员广播消息。

客户端服务发现

客户端服务发现是 JWorkPlace 中客户端开发的一个关键问题。 net.jini.lookup.ServiceDiscoveryManager 为客户端提供了服务发现支持。在 JWorkPlace 中,定义了两个辅助类 ClientStarter ClientLookup 来使用该管理器。

ClientLookup 类的代码如下:

package org.jworkplace.client;

import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.lookup.ServiceDiscoveryManager;
import net.jini.lookup.LookupCache;
import net.jini.lookup.ServiceItemFilter;
import net.jini.lookup.ServiceDiscoveryListener;
import net.jini.discovery.DiscoveryManagement;
import net.jini.lease.LeaseRenewalManager;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;

public class ClientLookup {
    protected ServiceDiscoveryManager lookupMgr;

    public ClientLookup() throws IOException {
        this(null, null);
    }

    public ClientLookup(DiscoveryManagement discMgr, LeaseRenewalManager leaseMgr) throws IOException {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }
        lookupMgr = new ServiceDiscoveryManager(discMgr, leaseMgr);
    }

    public ServiceDiscoveryListener getListener() {
        return null;
    }

    public ServiceItemFilter getFilter() {
        return null;
    }

    public boolean requiredFailureAction(ServiceTemplate template) {
        System.out.println(template);
        return false;
    }

    public ServiceRegistrar getLookupService() throws RemoteException {
        ServiceRegistrar registrar = null;
        Class[] types = {ServiceRegistrar.class};
        ServiceTemplate tmpl = new ServiceTemplate(null, types, null);
        ServiceItem item = getServiceItem(tmpl);
        if (!(item.service instanceof ServiceRegistrar)) {
            throw new RemoteException();
        }
        return (ServiceRegistrar)item.service;
    }

    public ServiceItem getServiceItem(ServiceTemplate template) {
        ServiceItem service = null;
        try {
            service = lookupMgr.lookup(template, getFilter(), 10000);
        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {}
        if (service == null) {
            boolean result = requiredFailureAction(template);
            if (result) System.exit(1);
        }
        return service;
    }

    public ServiceItem[] getServiceItems(ServiceTemplate template) {
        ServiceItem[] service = new ServiceItem[0];
        try {
            service = lookupMgr.lookup(template, 1, Integer.MAX_VALUE, getFilter(), 10000);
        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {}
        if (service == null) {
            boolean result = requiredFailureAction(template);
            if (result) System.exit(1);
        }
        return service;
    }

    public LookupCache createCache(ServiceTemplate template) throws RemoteException {
        return lookupMgr.createLookupCache(template, getFilter(), getListener());
    }

    public void terminate() {
        lookupMgr.terminate();
    }
}

ClientLookup 类的主要功能是使用 ServiceDiscoveryManager 进行服务发现。在构造函数中,会创建 ServiceDiscoveryManager 实例,并设置安全管理器。通过 getServiceItem getServiceItems 方法可以查找单个或多个服务。同时,还提供了创建客户端缓存和终止发现过程的方法。

需要注意的是, ServiceDiscoveryManager 会导出一个远程 ServiceDiscoveryListener 对象,因此客户端必须运行一个 HTTP 服务器,并提供代码库,以便查找服务能够访问必要的类。客户端的 jar 文件中需要包含以下四个文件:
- net.jini.core.event.RemoteEvent.class
- net.jini.core.event.RemoteEventListener.class
- net.jini.core.event.UnknownEventException.class
- net.jini.lookup.ServiceDiscoveryManager$LookupCacheImpl$LookupListener_Stub.class

ServiceUI 项目

ServiceUI 项目是 Jini 社区的一个项目,旨在标准化 Jini 服务的用户界面。该项目定义了三个用于将用户界面与 Jini 服务关联的项目:用户界面本身、生成 UI 的用户界面工厂以及描述 UI 的用户界面描述符。

以下是创建 UIDescriptor 条目的代码示例:

// describe the UI in a Set
Set typeNames = new HashSet();
// signifies this factory produces a JFrame
typeNames.add(JFrameFactory.TYPE_NAME);
Set attribs = new HashSet();
attribs.add(new UIFactoryTypes(typeNames));
// create the factory object
MarshalledObject factory = null;
try {
    // WorkPlaceFactory implements the factory method
    factory = new MarshalledObject(new WorkPlaceFactory());
} catch (Exception e) {
    e.printStackTrace();
    System.exit(1);
}
// Create the UIDescriptor entry
Entry[] entries = new UIDescriptor(MainUI.ROLE, // Role string
    WorkPlaceFactory.TOOLKIT, // Toolkit string
    attribs, // attribute objects
    factory); // UI factory

当前版本的 Jini 服务 UI API 定义了八个工厂接口,包括 DialogFactory FrameFactory JComponentFactory 等。这些接口用于生成不同类型的用户界面。

WorkPlaceFactory 类实现了 JFrameFactory 接口,用于创建 WorkPlaceFrame

package org.jworkplace.workplace;
import javax.swing.JFrame;
import net.jini.core.entry.Entry;
import net.jini.core.lookup.ServiceItem;
import net.jini.lookup.entry.UIDescriptor;
import net.jini.lookup.ui.attribute.UIFactoryTypes;
import net.jini.lookup.ui.factory.JFrameFactory;
import net.jini.lookup.ui.MainUI;

public class WorkPlaceFactory implements JFrameFactory {
    public JFrame getJFrame(Object obj) {
        if (!(obj instanceof ServiceItem)) {
            return null;
        }
        ServiceItem item = (ServiceItem)obj;
        // Get the attribute set
        Entry[] entries = item.attributeSets;
        // loop through attributes looking for UIDescriptor
        for (int i = 0; i < entries.length; i++) {
            if (entries[i] instanceof UIDescriptor) {
                UIDescriptor descriptor = (UIDescriptor)entries[i];
                // Ensure the role of this descriptor is for the MainUI
                if (descriptor.role.equals(net.jini.lookup.ui.MainUI.ROLE)) {
                    // Now create JFrame for WorkPlace, passing the ServiceItem
                    JFrame frame = new WorkPlaceFrame(item, FRAME_TITLE);
                    return frame;
                }
            }
        }
        return null;
    }
}

WorkPlaceFrame 类则确保 ServiceItem 实现了 IndexManager 接口,并初始化 WorkPlaceController

package org.jworkplace.workplace;
import net.jini.core.lookup.ServiceItem;
import net.jini.lookup.ui.MainUI;
import org.jworkplace.client.ServiceFrame;
import org.jworkplace.content.IndexManager;

public class WorkPlaceFrame extends ServiceFrame {
    public WorkPlaceFrame(ServiceItem item, String name) {
        super(item, name);
        if (item.service instanceof IndexManager) {
            WorkPlaceController workPlace = new WorkPlaceController();
            workPlace.initialize(item.service);
            getContentPane().add(workPlace);
            this.pack();
        }
    }
}
应用运行步骤

要运行 JWorkPlace,需要按照以下步骤进行操作:
1. 启动共享服务器
- 切换到相关目录,找到 services/scripts 目录下的 startShare.cmd 脚本。
- 编辑 PORT MYSHARE 变量,使其与你的安装相匹配。默认情况下,脚本使用端口 8081 和目录 chapter10\example1\MySpace 作为内容共享目录。
- 运行脚本:

C:\JiniJavaSpaces\Chapter10\services\scripts>startShare

以下是 startShare.cmd 脚本的内容:

@echo off
@call setup.cmd
set PORT=8081
set MYSHARE=chapter10\example1\MySpace
echo Jini and JavaSpaces Application Development
echo -------------------------------------------
echo Jini install directory          %JINI_HOME%
echo Examples install directory      %JWORK_HOME%
echo Default share port              %PORT%
echo Default share space             %JWORK_HOME%\%MYSHARE%
echo -------------------------------------------
echo Starting the Share Server...
java -jar %JINI_HOME%\lib\tools.jar -port 8081 -dir %JWORK_HOME%\%MYSHARE% -trees -verbose
  1. 启动事务服务和 JavaSpaces 服务
    • 检查 services/scripts 目录下的 startMahalo.cmd startOutrigger.cmd 脚本,并运行它们,以确保 mahalo 事务服务和 outrigger JavaSpaces 服务正常运行。
  2. 启动工作场所服务
    • 运行 services/scripts 目录下的 startWorkPlace1.cmd 脚本:
C:\JiniJavaSpaces\chapter10\services\scripts\startWorkPlace1.cmd
  1. 启动客户端
    • 编辑 chapter10/example1 目录下的 startClient.cmd 脚本,设置以下两个属性:
-Dorg.jworkplace.workport=%PORT%
-Dorg.jworkplace.workspace=%MYSHARE%

确保这些属性与 startShare.cmd 脚本中设置的 PORT MYSHARE 变量相匹配。
- 运行脚本:

C:\JiniJavaSpaces\chapter10\example1\startClient.cmd

在运行 JWorkPlace 应用后,你需要创建一个账户,然后创建一个共享空间,将本地目录映射到内容空间名称。可以使用“Add”按钮将文件添加到共享空间中。同时,通过界面的左右面板,你可以查看已定义的空间和所有用户,并通过选择表格中的条目并按下“share”按钮来将空间映射到用户。

通过以上步骤和功能介绍,你可以全面了解 JWorkPlace 应用的开发和运行过程,包括内容空间管理、消息服务、客户端服务发现、ServiceUI 项目等方面的知识。希望这些内容能帮助你更好地使用和开发 JWorkPlace 应用。

JWorkPlace 应用开发全解析(续)

服务 UI 项目深入分析

在上半部分我们介绍了 ServiceUI 项目的基本概念和部分代码实现,接下来我们进一步深入分析其相关类和接口。

服务 UI 工厂接口

当前版本的 Jini 服务 UI API 定义了八个工厂接口,这些接口在创建不同类型的用户界面时发挥着重要作用。以下是这些接口及其功能的详细介绍:

接口名称 功能描述
DialogFactory 返回一个依赖于 AWT 库但不依赖于 Swing 库的 java.awt.Dialog 或其子类的实例
FrameFactory 返回一个依赖于 AWT 库但不依赖于 Swing 库的 java.awt.Frame 或其子类的实例
JComponentFactory 返回一个依赖于 AWT 和 Swing 库的 javax.swing.JComponent 或其子类的实例
JDialogFactory 返回一个依赖于 AWT 和 Swing 库的 javax.swing.JDialog 或其子类的实例
JFrameFactory 返回一个依赖于 AWT 和 Swing 库的 javax.swing.JFrame 或其子类的实例
JWindowFactory 返回一个依赖于 AWT 和 Swing 库的 javax.swing.JWindow 或其子类的实例
PanelFactory 返回一个依赖于 AWT 库但不依赖于 Swing 库的 java.awt.Panel 或其子类的实例
WindowFactory 返回一个依赖于 AWT 库但不依赖于 Frame Dialog java.awt.Window 或其子类的实例

这些工厂接口为开发者提供了丰富的选择,使得可以根据不同的需求创建出多样化的用户界面。

WorkPlaceFactory 类的工作流程

WorkPlaceFactory 类实现了 JFrameFactory 接口,其主要功能是创建 WorkPlaceFrame 。下面是其工作流程的 mermaid 流程图:

graph TD;
    A[调用 getJFrame 方法] --> B{传入对象是否为 ServiceItem};
    B -- 否 --> C[返回 null];
    B -- 是 --> D[获取 ServiceItem 的属性集];
    D --> E[遍历属性集查找 UIDescriptor];
    E -- 未找到 --> C;
    E -- 找到 --> F{UIDescriptor 的角色是否为 MainUI};
    F -- 否 --> C;
    F -- 是 --> G[创建 WorkPlaceFrame 并返回];

从流程图可以清晰地看到, WorkPlaceFactory 类首先会检查传入的对象是否为 ServiceItem ,如果不是则直接返回 null 。如果是,则获取其属性集并遍历查找 UIDescriptor 。找到后,会检查其角色是否为 MainUI ,如果是则创建并返回 WorkPlaceFrame ,否则返回 null

服务控制器类分析

在 JWorkPlace 应用中,服务控制器类负责初始化和管理与服务相关的用户界面组件。下面我们详细分析几个重要的服务控制器类。

ServiceController 类

ServiceController 是一个抽象类,它定义了一个抽象方法 initialize ,用于初始化服务对象。以下是其代码:

import javax.swing.JComponent;

public abstract class ServiceController extends JComponent {
    abstract public void initialize(Object service);
}

这个抽象类为具体的服务控制器类提供了一个统一的接口,使得不同的服务控制器可以按照相同的方式进行初始化。

AccountController 类

AccountController ServiceController 的一个具体实现类,它用于初始化与 AccountManager 相关的用户界面组件。以下是其代码:

import java.awt.BorderLayout;
import org.jworkplace.ui.ServiceController;
import org.jworkplace.client.WorkPlaceClient;

public class AccountController extends ServiceController {
    private AccountEditor editor;
    private AccountModel model;
    private static String accountMgrClass = AccountManager.class.getName();

    public AccountController() {
        super();
    }

    public void initialize(Object object) {
        AccountManager accountMgr = null;
        if (object instanceof AccountManager)
            accountMgr = (AccountManager) object;
        else
            accountMgr = getServiceInterface();

        model = new AccountModel(accountMgr);
        editor = new AccountEditor(model);
        setLayout(new BorderLayout());
        add(editor, BorderLayout.CENTER);
    }

    public AccountManager getServiceInterface() {
        AccountManager manager = null;
        try {
            manager = (AccountManager) WorkPlaceClient.getServiceInterface(Class.forName(accountMgrClass));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return manager;
    }
}

AccountController 类的 initialize 方法首先会检查传入的对象是否为 AccountManager ,如果是则直接使用该对象,否则通过 getServiceInterface 方法获取 AccountManager 实例。然后,它会创建 AccountModel AccountEditor ,并将 AccountEditor 添加到界面中。

JWorkPlace 应用的使用场景和优势

JWorkPlace 应用在团队协作和资源共享方面具有显著的优势,以下是一些具体的使用场景和优势分析。

使用场景
  • 团队协作 :团队成员可以通过 JWorkPlace 的消息服务进行实时沟通,同时可以共享和管理团队的文档和资源。例如,在一个项目开发过程中,团队成员可以在共享空间中上传和下载项目文档,通过消息通道交流项目进展和问题。
  • 资源管理 :用户可以将本地目录映射到内容空间名称,方便地管理和共享自己的文件。同时,通过内容空间管理功能,可以控制不同用户对文件的访问权限。
优势
  • 标准化用户界面 :ServiceUI 项目为 Jini 服务提供了标准化的用户界面,使得不同的服务可以具有统一的外观和操作方式,提高了用户体验。
  • 便捷的服务发现 :通过 ServiceDiscoveryManager 和相关辅助类,客户端可以方便地发现和使用所需的服务,减少了开发的复杂度。
  • 丰富的功能模块 :JWorkPlace 应用包含了内容空间管理、消息服务、账户管理等多个功能模块,满足了用户在不同场景下的需求。
总结

通过对 JWorkPlace 应用的全面分析,我们了解了其内容空间管理、消息服务、客户端服务发现、ServiceUI 项目等方面的功能和实现细节。同时,我们也介绍了服务 UI 项目的工厂接口、服务控制器类的作用以及 JWorkPlace 应用的使用场景和优势。

在实际开发和使用过程中,开发者可以根据自己的需求对这些功能进行定制和扩展,充分发挥 JWorkPlace 应用的优势。希望本文能为开发者和使用者提供有价值的参考,帮助他们更好地理解和应用 JWorkPlace 应用。

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
标题中的"EthernetIP-master.zip"压缩文档涉及工业自动化领域的以太网通信协议EtherNet/IP。该协议由罗克韦尔自动化公司基于TCP/IP技术架构开发,已广泛应用于ControlLogix系列控制设备。该压缩包内可能封装了协议实现代码、技术文档或测试工具等核心组件。 根据描述信息判断,该资源主要用于验证EtherNet/IP通信功能,可能包含测试用例、参数配置模板及故障诊断方案。标签系统通过多种拼写形式强化了协议主题标识,其中"swimo6q"字段需结合具体应用场景才能准确定义其技术含义。 从文件结构分析,该压缩包采用主分支命名规范,符合开源项目管理的基本特征。解压后预期可获取以下技术资料: 1. 项目说明文档:阐述开发目标、环境配置要求及授权条款 2. 核心算法源码:采用工业级编程语言实现的通信协议栈 3. 参数配置文件:预设网络地址、通信端口等连接参数 4. 自动化测试套件:包含协议一致性验证和性能基准测试 5. 技术参考手册:详细说明API接口规范与集成方法 6. 应用示范程序:展示设备数据交换的标准流程 7. 工程构建脚本:支持跨平台编译和部署流程 8. 法律声明文件:明确知识产权归属及使用限制 该测试平台可用于构建协议仿真环境,验证工业控制器与现场设备间的数据交互可靠性。在正式部署前开展此类测试,能够有效识别系统兼容性问题,提升工程实施质量。建议用户在解压文件后优先查阅许可协议,严格遵循技术文档的操作指引,同时需具备EtherNet/IP协议栈的基础知识以深入理解通信机制。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值