// Copyright 2004-2014 Jim Voris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.qumasoft.clientapi;
import com.qumasoft.qvcslib.ArchiveDirManagerProxy;
import com.qumasoft.qvcslib.QVCSConstants;
import com.qumasoft.qvcslib.ServerProperties;
import com.qumasoft.qvcslib.TransportProxyInterface;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
/**
* Implementation of the ClientAPIContext interface. Use the
* {@link ClientAPIFactory#createClientAPIContext() createClientAPIContext}
* method to create an instance of this class.
* @author Jim Voris
*/
class ClientAPIContextImpl implements ClientAPIContext {
private final AtomicReference<String> appendedPath = new AtomicReference<>();
private final AtomicReference<String> fileName = new AtomicReference<>();
private final AtomicReference<String> password = new AtomicReference<>();
private final AtomicReference<String> projectName = new AtomicReference<>();
private final AtomicReference<String> serverIPAddress = new AtomicReference<>();
private final AtomicReference<String> viewName = new AtomicReference<>();
private final AtomicReference<String> userName = new AtomicReference<>();
private final AtomicReference<Boolean> recurseFlag = new AtomicReference<>(false);
private final AtomicReference<Boolean> preserveStateFlag = new AtomicReference<>(false);
private final AtomicReference<Boolean> loggedInFlag = new AtomicReference<>(false);
private final AtomicReference<Integer> port = new AtomicReference<>(0);
/**
* The list of project names we get from the server.
*/
private String[] serverProjectNames = null;
/**
* The list of view names for the current project.
*/
private String[] projectViewNames = null;
/**
* The project properties for the respective projects.
*/
private Properties[] projectProperties = null;
/**
* The map of appended paths.
*/
private Map<String, Object> appendedPathMap = null;
/*
* The map of archiveDirManagerProxy objects.
*/
private Map<String, ArchiveDirManagerProxy> archiveDirManagerProxyMap = null;
/**
* The transport proxy. Used to communicate with the server.
*/
private TransportProxyInterface transportProxy = null;
/**
* An object we use for synchronization.
*/
private final Object syncObject = new Object();
/**
* Server properties.
*/
private ServerProperties serverProperties = null;
/**
* The most recent activity.
*/
private Date mostRecentActivity = null;
/**
* Default constructor. Set the view name to 'Trunk' by default.
*/
public ClientAPIContextImpl() {
setViewName(QVCSConstants.QVCS_TRUNK_VIEW);
}
/**
* Get the user name.
*
* @return the user name.
*/
@Override
public String getUserName() {
return this.userName.get();
}
/**
* Set the user name.
*
* @param user the user name used to login to the QVCS-Enterprise
* server.
*/
@Override
public void setUserName(String user) {
this.userName.set(user);
}
/**
* Get the password. This is the password for the user name so that the
* username/password pair can be used to login to the QVCS-Enterprise
* server.
*
* @return the password.
*/
@Override
public String getPassword() {
return this.password.get();
}
/**
* Set the password. This is the password for the user name so that the
* username/password pair can be used to login to the QVCS-Enterprise
* server.
*
* @param pw the password.
*/
@Override
public void setPassword(String pw) {
this.password.set(pw);
}
/**
* Get the QVCS-Enterprise server IP address. This is the IP address that
* defines the network location of the QVCS-Enterprise server.
*
* @return the IP address of the QVCS-Enterprise server.
*/
@Override
public String getServerIPAddress() {
return this.serverIPAddress.get();
}
/**
* Set the QVCS-Enterprise server IP address. The QVCS-Enterprise client API
* will attempt to communicate with the QVCS-Enterprise server located at
* this IP address.
*
* @param serverIPAddr the server IP address.
*/
@Override
public void setServerIPAddress(String serverIPAddr) {
this.serverIPAddress.set(serverIPAddr);
}
/**
* Get the port number where the QVCS-Enterprise server is listening for
* connections from QVCS-Enterprise clients.
*
* @return the port number.
*/
@Override
public Integer getPort() {
return this.port.get();
}
/**
* Set the port number that the QVCS-Enterprise client API will use when
* attempting to establish a connection to the QVCS-Enterprise server. The
* server should be listening for client connections on this port number.
*
* @param prt the port number used by the QVCS-Enterprise server to listen
* for client connections.
*/
@Override
public void setPort(Integer prt) {
this.port.set(prt);
}
/**
* Get the project name.
*
* @return the project name.
*/
@Override
public String getProjectName() {
return this.projectName.get();
}
/**
* Set the project name. This defines the project that you are interested
* in. The client API requests will request data from the project named
* here.
*
* @param project the name of the QVCS-Enterprise project that you are
* interested in.
*/
@Override
public void setProjectName(String project) {
this.projectName.set(project);
}
/**
* Get the view name.
*
* @return the view name.
*/
@Override
public String getViewName() {
return this.viewName.get();
}
/**
* Set the view name. Typically (and by default), this will be the 'Trunk'
* view.
*
* @param view the view that you are interested in.
*/
@Override
public final void setViewName(String view) {
this.viewName.set(view);
}
/**
* Get the appendedPath.
*
* @return the appended path.
*/
@Override
public String getAppendedPath() {
return this.appendedPath.get();
}
/**
* Set the appended path. The 'appended path' identifies the sub-directory
* of the view that you are interested in. For example, if you are
* interested in the root directory of a view, then the appended path would
* be the empty string (e.g. ""); if you are interested in the
* source/java/com/qumasoft/utility sub-directory, then the appended path
* would be "source/java/com/qumasoft/utility".
*
* @param path the directory within the view that you are interested
* in.
*/
@Override
public void setAppendedPath(String path) {
this.appendedPath.set(path);
}
/**
* Get the file name.
*
* @return the file name.
*/
@Override
public String getFileName() {
return this.fileName.get();
}
/**
* Set the file name. This should be the file name for an individual file
* that you are interested in. It should include no directory components at
* all (the directory component is specified via the setAppendedPath()
* method).
*
* @param fileNm the file name.
*/
@Override
public void setFileName(String fileNm) {
this.fileName.set(fileNm);
}
/**
* Get the recurse flag. This flag is used to determine whether API request
* applies to just the directory defined by the appended path, or if it
* applies recursively to include in addition all the directories beneath
* the appended path directory.
*
* @return the recurse flag.
*/
@Override
public boolean getRecurseFlag() {
return this.recurseFlag.get();
}
/**
* Set the recurse flag. This flag is used to determine whether API request
* applies to just the directory defined by the appended path, or if it
* applies recursively to include in addition all the directories beneath
* the appended path directory.
*
* @param flag the value for the recurse flag.
*/
@Override
public void setRecurseFlag(boolean flag) {
this.recurseFlag.set(flag);
}
/**
* <p>
* Get the preserveState flag. This flag indicates whether calls through the
* client API are stateless (the default), or stateful. If the calls are
* stateless, then no state is preserved from one call on the ClientAPI to
* the next: the client logs in to the server for each call, and logs out
* from the server when the call is completed. If this flag is set to
* preserve state (true), then the client api will preserve state across
* calls when it can. Performance will be better if this flag is set to
* true. By default, its value is <b>false</b>.</p>
* <p>
* Some calls will force the client to disconnect from the server and state
* will be discarded. For example, if the preserve state is set to true, and
* the client performs a
* {@link com.qumasoft.clientapi.ClientAPI#getProjectList(com.qumasoft.clientapi.ClientAPIContext) getProjectList}
* call followed by a
* {@link #setServerIPAddress(java.lang.String) setServerIPAddress} call on
* this class, then state will be lost after the <b>setServerIPAddress</b>
* call since the server end point has now changed.</p>
*
* @return the current value of the preserveState flag.
*/
@Override
public boolean getPreserveStateFlag() {
return this.preserveStateFlag.get();
}
/**
* Set the preserveState flag. See
* {@link #getPreserveStateFlag() getPreserveStateFlag} for a description of
* how this flag works. You should set this flag before beginning method
* calls on the ClientAPI.
*
* @param flag the new value for the preserveState flag.
*/
@Override
public void setPreserveStateFlag(boolean flag) {
this.preserveStateFlag.set(flag);
}
boolean getLoggedInFlag() {
return this.loggedInFlag.get();
}
void setLoggedInFlag(boolean flag) {
this.loggedInFlag.set(flag);
}
TransportProxyInterface getTransportProxy() {
synchronized (getSyncObject()) {
return this.transportProxy;
}
}
void setTransportProxy(TransportProxyInterface transportPxy) {
synchronized (getSyncObject()) {
this.transportProxy = transportPxy;
}
}
Properties[] getProjectProperties() {
synchronized (getSyncObject()) {
return this.projectProperties;
}
}
void setProjectProperties(Properties[] properties) {
synchronized (getSyncObject()) {
if (properties != null) {
Properties[] localPropertiesArray = new Properties[properties.length];
System.arraycopy(properties, 0, localPropertiesArray, 0, properties.length);
this.projectProperties = localPropertiesArray;
} else {
this.projectProperties = null;
}
}
}
String[] getServerProjectNames() {
synchronized (getSyncObject()) {
return this.serverProjectNames;
}
}
void setServerProjectNames(String[] projectNames) {
synchronized (getSyncObject()) {
if (projectNames != null) {
String[] localProjectNames = new String[projectNames.length];
System.arraycopy(projectNames, 0, localProjectNames, 0, projectNames.length);
this.serverProjectNames = localProjectNames;
} else {
this.serverProjectNames = null;
}
}
}
Map<String, Object> getAppendedPathMap() {
synchronized (getSyncObject()) {
return this.appendedPathMap;
}
}
void setAppendedPathMap(Map<String, Object> map) {
synchronized (getSyncObject()) {
this.appendedPathMap = map;
}
}
Map<String, ArchiveDirManagerProxy> getArchiveDirManagerProxyMap() {
synchronized (getSyncObject()) {
return this.archiveDirManagerProxyMap;
}
}
void setArchiveDirManagerProxyMap(Map<String, ArchiveDirManagerProxy> map) {
synchronized (getSyncObject()) {
this.archiveDirManagerProxyMap = map;
}
}
ServerProperties getServerProperties() {
synchronized (getSyncObject()) {
return this.serverProperties;
}
}
void setServerProperties(ServerProperties props) {
synchronized (getSyncObject()) {
this.serverProperties = props;
}
}
Object getSyncObject() {
return this.syncObject;
}
String[] getProjectViewNames() {
synchronized (getSyncObject()) {
return this.projectViewNames;
}
}
void setProjectViewNames(String[] projectVwNames) {
synchronized (getSyncObject()) {
if (projectVwNames != null) {
String[] localProjectViewNames = new String[projectVwNames.length];
System.arraycopy(projectVwNames, 0, localProjectViewNames, 0, projectVwNames.length);
this.projectViewNames = localProjectViewNames;
} else {
this.projectViewNames = null;
}
}
}
/**
* @return the mostRecentActivity
*/
public Date getMostRecentActivity() {
synchronized (getSyncObject()) {
return mostRecentActivity;
}
}
/**
* @param mostRecentActvity the mostRecentActivity to set
*/
public void setMostRecentActivity(Date mostRecentActvity) {
synchronized (getSyncObject()) {
this.mostRecentActivity = mostRecentActvity;
}
}
}