ClientResourceManager.java
/*
** Module : ClientResourceManager.java
** Abstract : Management of client OS resources.
**
** Copyright (c) 2022-2024, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------------Description----------------------------------------
** 001 CA 20220515 Created initial version.
** RFB 20220524 Fixed minor javadoc error.
** CA 20220918 Allow legacy client sockets to be ran on FWD server instead of FWD client.
** 002 HC 20230427 Implemented server-side file-system resource. File operations performed on
** client can be optionally performed directly on server without the expensive
** remote call.
** 003 HC 20230517 Implemented server-side web service calling.
** 004 GBB 20240826 Replacing the single per JVM initialize call with a synchronized call in the constructor.
** Adding initializeEnvironments. Replacing type constants with enum OsResourceType.
** 005 GBB 20240912 Adding support for types mail, launcher and streams.
** Renaming ClientSideResourceManager to ClientResourceManager.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.util.osresource;
import com.goldencode.p2j.net.*;
import com.goldencode.p2j.ui.chui.*;
import com.goldencode.p2j.util.*;
import java.util.concurrent.atomic.*;
/**
* Management of OS resources on client-side.
* <p>
* For each server-side OS resource, this will obtain a network proxy. Otherwise, a local proxy is generated.
*/
class ClientResourceManager
extends OSResourceManager
{
/**
* Package-private constructor.
*/
ClientResourceManager()
{
initializeMemptr();
initializeLibrary();
initializeSocket();
initializeFileSystem();
initializeWebService();
initializeEnvironments();
initializeEmailSender();
initializeProcessLauncher();
initializeStreamHelper();
}
/**
* Initialize the OS {@link OsResourceType#MEMPTR} resource.
* <p>
* If the {@link #isServerSide(OsResourceType)} memptr is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link LowLevelBuffer} network or local object.
*/
@Override
LowLevelBuffer initializeMemptr()
{
LowLevelBuffer buf = (LowLevelBuffer) resources.get(OsResourceType.MEMPTR);
if (buf != null)
{
return buf;
}
if (isServerSide(OsResourceType.MEMPTR))
{
buf = (LowLevelBuffer) RemoteObject.obtainNetworkInstance(LowLevelBuffer.class);
}
else
{
buf = new MemoryDaemon(false);
}
resources.put(OsResourceType.MEMPTR, buf);
return buf;
}
/**
* Initialize the OS {@link OsResourceType#LIBRARY} resource.
* <p>
* If the {@link #isServerSide(OsResourceType)} library is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link NativeAPICaller} network or local object.
*/
@Override
NativeAPICaller initializeLibrary()
{
NativeAPICaller libd = (NativeAPICaller) resources.get(OsResourceType.LIBRARY);
if (libd != null)
{
return libd;
}
if (isServerSide(OsResourceType.LIBRARY))
{
libd = (NativeAPICaller) RemoteObject.obtainNetworkInstance(NativeAPICaller.class);
}
else
{
libd = new LibraryDaemon(false);
}
resources.put(OsResourceType.LIBRARY, libd);
return libd;
}
/**
* Initialize the OS {@link OsResourceType#SOCKET} resource.
* <p>
* If the {@link #isServerSide(OsResourceType)} client-socket is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link LowLevelSocket} network or local object.
*/
@Override
LowLevelSocket initializeSocket()
{
LowLevelSocket lls = (LowLevelSocket) resources.get(OsResourceType.SOCKET);
if (lls != null)
{
return lls;
}
if (isServerSide(OsResourceType.SOCKET))
{
lls = (LowLevelSocket) RemoteObject.obtainNetworkInstance(LowLevelSocket.class);
}
else
{
lls = new LowLevelSocketImpl(false);
}
resources.put(OsResourceType.SOCKET, lls);
return lls;
}
/**
* Initialize the OS {@link OsResourceType#FILESYSTEM} resource.
* <p>
* If the {@link #isServerSide(OsResourceType)} file system is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link FileSystem} network or local object.
*/
@Override
FileSystem initializeFileSystem()
{
FileSystem fs = (FileSystem) resources.get(OsResourceType.FILESYSTEM);
if (fs != null)
{
return fs;
}
if (isServerSide(OsResourceType.FILESYSTEM))
{
fs = (FileSystem) RemoteObject.obtainNetworkInstance(FileSystem.class);
}
else
{
fs = FileSystemDaemon.getInstance(false, false);
}
resources.put(OsResourceType.FILESYSTEM, fs);
return fs;
}
/**
* Initialize the OS {@link OsResourceType#WEBSERVICE} resource.
* <p>
* If the web service is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link WebService} network or local object.
*/
@Override
WebService initializeWebService()
{
WebService ws = (WebService) resources.get(OsResourceType.WEBSERVICE);
if (ws != null)
{
return ws;
}
if (isServerSide(OsResourceType.WEBSERVICE))
{
ws = (WebService) RemoteObject.obtainNetworkInstance(WebService.class);
}
else
{
ws = WebServiceImpl.getInstance(false);
}
resources.put(OsResourceType.WEBSERVICE, ws);
return ws;
}
/**
* Initialize the OS {@link OsResourceType#ENVIRONMENTS} resource.
* <p>
* If the resource environments is server-side, this returns a network proxy.
* <p>
* Otherwise, a local proxy is returned.
*
* @return The {@link EnvironmentAccessor} network or local object.
*/
@Override
EnvironmentAccessor initializeEnvironments()
{
EnvironmentAccessor ea = (EnvironmentAccessor) resources.get(OsResourceType.ENVIRONMENTS);
if (ea != null)
{
return ea;
}
if (isServerSide(OsResourceType.ENVIRONMENTS))
{
// no server registered, no calls expected from the client
}
else
{
ThinClient tc = ThinClient.getInstance();
ea = new EnvironmentDaemon(tc.getEnvVersion(), false, tc.getUnderWindows(), tc.getClientStorage());
}
resources.put(OsResourceType.ENVIRONMENTS, ea);
return ea;
}
/**
* Initialize the OS {@link OsResourceType#MAIL} resource.
*
* @return The {@link RemoteEmailSender} network or local object.
*/
@Override
RemoteEmailSender initializeEmailSender()
{
RemoteEmailSender mailSender = (RemoteEmailSender) resources.get(OsResourceType.MAIL);
if (mailSender != null)
{
return mailSender;
}
if (isServerSide(OsResourceType.MAIL))
{
// no server registered, no calls expected from the client
mailSender = (RemoteEmailSender) RemoteObject.obtainNetworkInstance(RemoteEmailSender.class);
}
else
{
mailSender = new EmailDaemon(false);
}
resources.put(OsResourceType.MAIL, mailSender);
return mailSender;
}
/**
* Initialize the OS {@link OsResourceType#LAUNCHER} resource.
*
* @return The {@link Launcher} network or local object.
*/
@Override
Launcher initializeProcessLauncher()
{
Launcher launcher = (Launcher) resources.get(OsResourceType.LAUNCHER);
if (launcher != null)
{
return launcher;
}
if (isServerSide(OsResourceType.LAUNCHER))
{
// no server registered, no calls expected from the client
launcher = (Launcher) RemoteObject.obtainNetworkInstance(Launcher.class);
}
else
{
launcher = new ProcessDaemon(ThinClient.getInstance(), false);
}
resources.put(OsResourceType.LAUNCHER, launcher);
return launcher;
}
/**
* Initialize the OS {@link OsResourceType#STREAMS} resource.
*
* @return The {@link StreamDaemon} network or local object.
*/
@Override
StreamHelper initializeStreamHelper()
{
StreamHelper streams = (StreamHelper) resources.get(OsResourceType.STREAMS);
if (streams != null)
{
return streams;
}
if (isServerSide(OsResourceType.STREAMS))
{
// no server registered, no calls expected from the client
}
else
{
streams = new StreamDaemon(ThinClient.getInstance());
RemoteObject.registerServer(StreamHelper.class, streams, null, false);
}
resources.put(OsResourceType.STREAMS, streams);
return streams;
}
}