I'm a novice when it comes to JSPs and JAVA.
How do I get the output from the below code to display on a jsp, considering that it runs everything from the main and contains non-public methods, a nested static class etc?
I know that we are not supposed to use java code on jsp but my first step in this proof on concept exercise is to get the code running and returning data from a backend then I can set about using EL etc.
I can run the program, with the correct config settings, from within Eclipse and all works fine with the output appearing on the console but I'm really not sure how to access it from within a jsp.
How do I access the static class and static methods from a jsp if they aren't public?
All help greatly appreciated.
public class CustomDestinationDataProvider
{
static class MyDestinationDataProvider implements DestinationDataProvider
{
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName)
{
try
{
//read the destination from DB
Properties p = secureDBStorage.get(destinationName);
if(p!=null)
{
//check if all is correct, for example
if(p.isEmpty())
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
return p;
}
return null;
}
catch(RuntimeException re)
{
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener)
{
this.eL = eventListener;
}
public boolean supportsEvents()
{
return true;
}
//implementation that saves the properties in a very secure way
void changeProperties(String destName, Properties properties)
{
synchronized(secureDBStorage)
{
if(properties==null)
{
if(secureDBStorage.remove(destName)!=null)
eL.deleted(destName);
}
else
{
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
} // end of MyDestinationDataProvider
//business logic
void executeCalls(String destName)
{
JCoDestination dest;
try
{
dest = JCoDestinationManager.getDestination(destName);
dest.ping();
System.out.println("Destination " + destName + " works");
step4WorkWithTable(dest);
}
catch(JCoException e)
{
e.printStackTrace();
System.out.println("Execution on destination " + destName+ " failed");
}
}
static Properties getDestinationPropertiesFromUI()
{
//adapt parameters in order to configure a valid destination
Properties connectProperties = new Properties();
// Add code here to set config settings
return connectProperties;
}
public static void main(String[] args)
{
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
//register the provider with the JCo environment;
//catch IllegalStateException if an instance is already registered
try
{
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
}
catch(IllegalStateException providerAlreadyRegisteredException)
{
//somebody else registered its implementation,
//stop the execution
throw new Error(providerAlreadyRegisteredException);
}
String destName = "????";
CustomDestinationDataProvider test = new CustomDestinationDataProvider();
//set properties for the destination and ...
myProvider.changeProperties(destName, getDestinationPropertiesFromUI());
//... work with it
test.executeCalls(destName);
}
public static void step4WorkWithTable(JCoDestination dest) throws JCoException
{
JCoFunction function = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETLIST");
if(function == null)
throw new RuntimeException("BAPI_COMPANYCODE_GETLIST not found in SAP.");
try
{
function.execute(dest);
}
catch(AbapException e)
{
System.out.println(e.toString());
return;
}
JCoStructure returnStructure = function.getExportParameterList().getStructure("RETURN");
if (! (returnStructure.getString("TYPE").equals("")||returnStructure.getString("TYPE").equals("S")) )
{
throw new RuntimeException(returnStructure.getString("MESSAGE"));
}
JCoTable codes = function.getTableParameterList().getTable("COMPANYCODE_LIST");
for (int i = 0; i < codes.getNumRows(); i++)
{
codes.setRow(i);
System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME"));
}
//move the table cursor to first row
codes.firstRow();
for (int i = 0; i < codes.getNumRows(); i++, codes.nextRow())
{
function = dest.getRepository().getFunction("BAPI_COMPANYCODE_GETDETAIL");
if (function == null)
throw new RuntimeException("BAPI_COMPANYCODE_GETDETAIL not found in SAP.");
function.getImportParameterList().setValue("COMPANYCODEID", codes.getString("COMP_CODE"));
//We do not need the addresses, so set the corresponding parameter to inactive.
//Inactive parameters will be either not generated or at least converted.
function.getExportParameterList().setActive("COMPANYCODE_ADDRESS",false);
try
{
function.execute(dest);
}
catch (AbapException e)
{
System.out.println(e.toString());
return;
}
returnStructure = function.getExportParameterList().getStructure("RETURN");
if (! (returnStructure.getString("TYPE").equals("") ||
returnStructure.getString("TYPE").equals("S") ||
returnStructure.getString("TYPE").equals("W")) )
{
throw new RuntimeException(returnStructure.getString("MESSAGE"));
}
JCoStructure detail = function.getExportParameterList().getStructure("COMPANYCODE_DETAIL");
System.out.println(detail.getString("COMP_CODE") + '\t' +
detail.getString("COUNTRY") + '\t' +
detail.getString("CITY"));
}//for
}
}
Related
I have a messages.properties file that contains all string messages used in my application.
I would like to bind these messages to a java class fields and use directly in other classes.
Can this be achieved without using NLS? By some approach in javafx? Because I do not want to add eclipse dependency in UI classes.
Java provides property file reading capability right from the box. You can do adjustment to suit your actual use-case.
For example:
public final class Messages {
private Messages() {
loadFile();
}
private static final class ThreadSafeSingleton {
private static final Messages INSTANCE = new Messages();
}
public static Messages getInstance() {
return ThreadSafeSingleton.INSTANCE;
}
private final Properties props = new Properties();
private void loadFile() {
InputStream is = null;
try {
is = new FileInputStream("messages.properties");
props.load(is);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String getMessage(String key) {
if (key == null && key.isEmpty()) return "";
return props.getProperty(key);
}
}
Edit
In order to use these values as if it is a constant, you need to pretty much make everything static:
public final class Messages {
private Messages() {} // Not instantiable
private static final Properties props = loadFile(); // Make sure this static field is at the top
public static final String FOO = getMessage("foo");
public static final String BAR = getMessage("bar");
private static Properties loadFile() {
final Properties p = new Properties();
InputStream is = null;
try {
is = new FileInputStream("messages.properties");
p.load(is);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return p;
}
public static String getMessage(String key) {
if (key == null && key.isEmpty()) return "";
return props.getProperty(key);
}
}
Be warned again, the Properties field must always be the top-most field declared in the class, because the class loader will load the fields top-down for all static fields whose value is computed at runtime (i.e. set by a static method).
Another point, this example does not handles what happens if the file is not file - it simply returns a Properties that has no value.
Problem in creating a new workspace in an Eclipse RCP application.
When the RCP application is launched, a dialog is prompted to ask the workspace location.
When the location is given, then there is error saying "Could not launch the product because the specified workspace cannot be created.
The specified workspace directory is either invalid or read-only".
I have followed the code from IDEApplication.java from eclipse, but still I am facing same issue.
Application code:
#SuppressWarnings("restriction")
public class MyRcpApplication implements IApplication
{
private static final String METADATA_PROJECTS_PATH = "/.plugins/org.eclipse.core.resources/.projects";
private static final String METADATA_ROOT = ".metadata";
private static final String COMMAND_ARG = "--container";
private static final String SYSTEM_PROPERTY_EXIT_CODE = "eclipse.exitcode";
private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime";
private static final String VERSION_FILENAME = "version.ini";
private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
private Shell shell;
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
#Override
public Object start(final IApplicationContext context)
{
Display display = PlatformUI.createDisplay();
Shell shell = display.getActiveShell();
try
{
// for backward compatibility we need to clear the workspace before start also
cleanUpTheWorkSpace();
boolean instanceLocationCheck = checkInstanceLocation(shell, context.getArguments());
if (!instanceLocationCheck)
{
MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle,
"Could not launch the product because the associated workspace is currently in use by another My Application.");
return IApplication.EXIT_OK;
}
int returnCode = PlatformUI.createAndRunWorkbench(display, new MyApplicationWorkbenchAdvisor());
if (returnCode == PlatformUI.RETURN_RESTART)
{
// eclipse.exitcode system property may be set to re-launch
if (IApplication.EXIT_RELAUNCH.equals(Integer.getInteger(SYSTEM_PROPERTY_EXIT_CODE)))
{
return IApplication.EXIT_RELAUNCH;
}
return IApplication.EXIT_RESTART;
}
// if application return code is exit clean up the workspace
// cleanUpTheWorkSpace();
return IApplication.EXIT_OK;
}
finally
{
if (display != null)
{
display.dispose();
}
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc != null)
{
instanceLoc.release();
}
}
}
#SuppressWarnings("rawtypes")
private boolean checkInstanceLocation(final Shell shell, final Map arguments)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc == null)
{
MessageDialog.openError(shell, "Workspace is Mandatory", "IDEs need a valid workspace.");
return false;
}
// -data "/valid/path", workspace already set
if (instanceLoc.isSet())
{
// make sure the meta data version is compatible (or the user has
// chosen to overwrite it).
try
{
// Used to check whether are we launching My application from development environment or not
if (isDevLaunchMode(arguments))
{
return true;
}
// Used to check instance location is locked or not
if (instanceLoc.isLocked())
{
return false;
}
// we failed to create the directory.
// Two possibilities:
// 1. directory is already in use
// 2. directory could not be created
File workspaceDirectory = new File(instanceLoc.getURL().getFile());
if (workspaceDirectory.exists())
{
if (isDevLaunchMode(arguments))
{
return true;
}
MessageDialog.openError(
shell,
"Workspace Cannot Be Locked",
"Could not launch the product because the associated workspace at '" + workspaceDirectory.getAbsolutePath()
+ "' is currently in use by another Eclipse application");
}
else
{
MessageDialog
.openError(
shell,
"Workspace Cannot Be Created",
"Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only.");
}
}
catch (IOException e)
{
MessageDialog.openError(shell, "Internal Error", e.getMessage());
}
}
else
{
try
{
// -data #noDefault or -data not specified, prompt and set
ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc.getDefault());
boolean force = false;
while (true)
{
URL workspaceUrl = promptForWorkspace(shell, launchData, force);
if (workspaceUrl == null)
{
return false;
}
// if there is an error with the first selection, then force the
// dialog to open to give the user a chance to correct
force = true;
try
{
// the operation will fail if the url is not a valid
// instance data area, so other checking is unneeded
if (instanceLoc.set(workspaceUrl, false))
{
launchData.writePersistedData();
writeWorkspaceVersion(workspaceUrl);
return true;
}
}
catch (IllegalStateException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceCannotBeSetMessage);
return false;
}
// by this point it has been determined that the workspace is
// already in use -- force the user to choose again
MessageDialog.openError(shell, IDEWorkbenchMessages
.IDEApplication_workspaceInUseTitle,
IDEWorkbenchMessages.
IDEApplication_workspaceInUseMessage);
}
}
catch (IllegalStateException | IOException e)
{
}
}
return true;
}
private static void writeWorkspaceVersion(final URL defaultValue)
{
Location instanceLoc = Platform.getInstanceLocation();
if (instanceLoc.isReadOnly())
{
// MessageDialog.openError(shell,"Read-Only Dialog", "Location was read-only");
System.out.println("Instance Got Locked......");
}
if ((instanceLoc == null) || instanceLoc.isReadOnly())
{
return;
}
File versionFile = getVersionFile(instanceLoc.getURL(), true);
if (versionFile == null)
{
return;
}
OutputStream output = null;
try
{
String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE;
output = new FileOutputStream(versionFile);
output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not write version file", //$NON-NLS-1$
StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e));
}
finally
{
try
{
if (output != null)
{
output.close();
}
}
catch (IOException e)
{
// do nothing
}
}
}
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#stop()
*/
#Override
public void stop()
{
if (!PlatformUI.isWorkbenchRunning())
{
return;
}
final IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
display.syncExec(new Runnable()
{
#Override
public void run()
{
if (!display.isDisposed())
{
workbench.close();
}
}
});
}
private URL promptForWorkspace(final Shell shell, final ChooseWorkspaceData launchData, boolean force)
{
URL url = null;
do
{
new ChooseWorkspaceDialog(shell, launchData, false, force).prompt(force);
String instancePath = launchData.getSelection();
if (instancePath == null)
{
return null;
}
// the dialog is not forced on the first iteration, but is on every
// subsequent one -- if there was an error then the user needs to be
// allowed to
force = true;
// create the workspace if it does not already exist
File workspace = new File(instancePath);
if (!workspace.exists())
{
workspace.mkdir();
}
try
{
// Don't use File.toURL() since it adds a leading slash that Platform does not
// handle properly. See bug 54081 for more details.
String path = workspace.getAbsolutePath().replace(File.separatorChar, '/');
url = new URL("file", null, path); //$NON-NLS-1$
}
catch (MalformedURLException e)
{
MessageDialog
.openError(
shell,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidTitle,
IDEWorkbenchMessages
.IDEApplication_workspaceInvalidMessage);
continue;
}
}
while (!checkValidWorkspace(shell, url));
return url;
}
private boolean checkValidWorkspace(final Shell shell, final URL url)
{
String version = readWorkspaceVersion(url);
// if the version could not be read, then there is not any existing
// workspace data to trample, e.g., perhaps its a new directory that
// is just starting to be used as a workspace
if (version == null)
{
return true;
}
final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE);
int workspace_version = Integer.parseInt(version);
// equality test is required since any version difference (newer
// or older) may result in data being trampled
if (workspace_version == ide_version)
{
return true;
}
// At this point workspace has been detected to be from a version
// other than the current ide version -- find out if the user wants
// to use it anyhow.
String title = "My App Titile"; //$NON-NLS-1$
String message = "My App Message";
MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL
| SWT.ICON_WARNING | SWT.APPLICATION_MODAL);
mbox.setText(title);
mbox.setMessage(message);
return mbox.open() == SWT.OK;
}
private static String readWorkspaceVersion(final URL workspace)
{
File versionFile = getVersionFile(workspace, false);
if ((versionFile == null) || !versionFile.exists())
{
return null;
}
try
{
// Although the version file is not spec'ed to be a Java properties
// file, it happens to follow the same format currently, so using
// Properties to read it is convenient.
Properties props = new Properties();
FileInputStream is = new FileInputStream(versionFile);
try
{
props.load(is);
}
finally
{
is.close();
}
return props.getProperty(WORKSPACE_VERSION_KEY);
}
catch (IOException e)
{
IDEWorkbenchPlugin.log("Could not read version file", new Status( //$NON-NLS-1$
IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH,
IStatus.ERROR,
e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$,
e));
return null;
}
}
private static File getVersionFile(final URL workspaceUrl, final boolean create)
{
if (workspaceUrl == null)
{
return null;
}
try
{
// make sure the directory exists
File metaDir = new File(workspaceUrl.getPath(), METADATA_FOLDER);
if (!metaDir.exists() && (!create || !metaDir.mkdir()))
{
return null;
}
// make sure the file exists
File versionFile = new File(metaDir, VERSION_FILENAME);
if (!versionFile.exists()
&& (!create || !versionFile.createNewFile()))
{
return null;
}
return versionFile;
}
catch (IOException e)
{
// cannot log because instance area has not been set
return null;
}
}
#SuppressWarnings("rawtypes")
private static boolean isDevLaunchMode(final Map args)
{
// see org.eclipse.pde.internal.core.PluginPathFinder.isDevLaunchMode()
if (Boolean.getBoolean("eclipse.pde.launch"))
{
return true;
}
return args.containsKey("-pdelaunch"); //$NON-NLS-1$
}
/**
* Deletes all the available projects in the workspace
*/
private void cleanUpTheWorkSpace()
{
// this will be the
String[] commands = Platform.getCommandLineArgs();
if (commands != null)
{
List<String> args = Arrays.asList(commands);
if (args.contains(COMMAND_ARG))
{
// if project is in the root delete it.. it will delete associated metadata
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
if (projects != null)
{
for (IProject project : projects)
{
try
{
project.delete(true, new NullProgressMonitor());
}
catch (CoreException e)
{
// msgHandler.post(MsgSeverity.ERROR, "Unable to clear the workspace");
}
}
}
// if project is not in the root but if its in the workspace delete the metadata too
File[] workSpaceFiles = Platform.getLocation().toFile().listFiles();
for (File file : workSpaceFiles)
{
if (METADATA_ROOT.equals(file.getName()))
{
File projectMeta = new File(file.getPath() + METADATA_PROJECTS_PATH);
if ((projectMeta != null) && projectMeta.exists())
{
File[] children = projectMeta.listFiles();
for (File child : children)
{
FileUtils.deleteQuietly(child);
}
}
}
/*
* else { FileUtils.deleteQuietly(file); }
*/
}
}
}
}
}
Try run Eclipse as administrator.
Your code is just calling
if (instanceLoc.isLocked())
{
return false;
}
to check if the workspace is locked, but is doing nothing to make the workspace locked so this will always fall through to the error code.
IDEApplication does this:
if (instanceLoc.lock()) {
writeWorkspaceVersion();
return null;
}
you need to do something similar.
Spring has made it so incredibly easy to set up application properties...but how would you do it without Spring?
I need to deploy a Java / Groovy application to a server where using Spring is out of the question... and I also don't have the liberty to install anything like Redis either. One option I am considering is to set up a Spring Cloud Config Server elsewhere and have my application consume properties from the config server. Trouble is, that is a bit of an overkill for my project now.
Could anyone suggest a way to do this in good, old, plain Java? :)
This is a really simple and basic example, but you can modify it as you like:
PropertyConfigurator.java
public class PropertiesConfigurator
{
Properties properties = new Properties();
String configInputPath = null;
InputStream configInputStream = null;
public PropertiesConfigurator(String configInputPath)
{
this.configInputPath = configInputPath;
}
public PropertiesConfigurator load() throws IOException, PropertyException
{
try
{
this.configInputStream = new FileInputStream(this.configInputPath);
// load a properties file
this.properties.load(this.configInputStream);
validate();
}
catch (IOException ex)
{
System.out.println("Failed load properties file: " + this.configInputPath);
throw ex;
}
catch (PropertyException ex)
{
System.out.println("One or more properties are empty");
throw ex;
}
finally
{
if (this.configInputStream != null)
{
try
{
this.configInputStream.close();
}
catch (IOException ex)
{
System.out.println("Failed to close input stream");
throw ex;
}
}
}
return this;
}
private void validate() throws PropertyException
{
Enumeration<?> e = this.properties.propertyNames();
while (e.hasMoreElements())
{
String key = (String) e.nextElement();
String value = this.properties.getProperty(key);
if (value.isEmpty())
{
System.out.println(String.format("Property %s is empty!", key));
throw new PropertyException("One or more properties are empty");
}
}
}
public String getProperty(String key)
{
return this.properties.getProperty(key);
}
#Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (!(o instanceof PropertiesConfigurator))
return false;
PropertiesConfigurator that = (PropertiesConfigurator) o;
if (properties != null ? !properties.equals(that.properties) : that.properties != null)
return false;
if (configInputPath != null ? !configInputPath.equals(that.configInputPath) : that.configInputPath != null)
return false;
return configInputStream != null ?
configInputStream.equals(that.configInputStream) :
that.configInputStream == null;
}
#Override
public int hashCode()
{
int result = properties != null ? properties.hashCode() : 0;
result = 31 * result + (configInputPath != null ? configInputPath.hashCode() : 0);
result = 31 * result + (configInputStream != null ? configInputStream.hashCode() : 0);
return result;
}
}
PropertyException.java
public class PropertyException extends Exception
{
public PropertyException()
{
}
public PropertyException(String message)
{
super(message);
}
public PropertyException(String message, Throwable throwable)
{
super(message, throwable);
}
}
MainRunner.java
public class MainRunner
{
public static void main(String[] args)
{
try
{
String configFilePath = "application.properties";
PropertiesConfigurator propertiesConfigurator = new PropertiesConfigurator(configFilePath).load();
String prop1 = propertiesConfigurator.getProperty("keyprop1");
// Do whatever you want with prop1
// ...
}
catch (PropertyException ex)
{
System.out.println("Failed to load properties");
System.exit(1);
}
catch (Exception ex)
{
System.out.println("Error in main application");
System.exit(1);
}
}
}
Example of application.properties
keyprop1=value1
keyprop2=value2
Again, it's very basic and you should definitely improve this code and add your logic, validation, etc.
Take a look at http://constretto.org. That's easy to use configuration framework.
I have developed a client/server chat application using Java and I wish to know how can I remove a user from an array. When a specific client log-in the username is saved in username array and client ID in client array. To allow the server to accept multiple clients, I am using threads. Now can anyone guide me on how to remove a user from the array and also close the connection for that user.
Adding a new client and saving the ID in client array
public class AddClient implements Runnable {
Thread t;
AddClient(String tot) {
t = new Thread(this, tot);
t.start();
}
public void run() {
while (true) {
try {
try {
waitClient();
} catch (Exception ex) {
ex.printStackTrace();
}
for (int i = 0; i < client.length; i++) {
if (client[i] == 0) {
client[i] = i + 1;
id = i;
break;
}
}
//set stream to send and receive data
out[client[id]] = new ObjectOutputStream(connect.getOutputStream());
out[client[id]].flush();
in[client[id]] = new ObjectInputStream(connect.getInputStream());
The username is saved in the username array
username[client[id]] = cm.sender; //Add user in username[] array
Removing user
public synchronized void removeUser(int number) {
int position = number;
System.out.println("Server removing user " + username[number] + "which is client " + number);
for (int i = 0; i <= client.length; i++) {
if (position == client[i]) {
System.out.println("User to be remove found");
try {
client[i + 1] = client[i];
in[position].close();
out[position].close();
username[position] = null;
position = position - 1;
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am trying to use HashTable to add and remove the client
public class ChatServerProtocol {
private String nick;
private AddClient a;
private Hashtable<String, AddClient> nicks = new Hashtable<String, AddClient>();
private boolean add_nick(String nick, AddClient a) {
if (nicks.containsKey(nick)) {
return false;
} else {
nicks.put(nick, a);
return true;
}
}
private boolean remove_nick(String nick, AddClient a) {
if (!(nicks.containsKey(nick))) {
return false;
} else {
nicks.remove(nick);
return true;
}
}
public ChatServerProtocol(AddClient a) throws IOException {
nick = null;
a = a;
}
But now how do I call the method add_nick. Whenever a client log-in the username is sent to the server and the server reads it as cm.sender. I also need to include the thread variable. So how to add the username so that later i can remove it.
ChatServerProtocol.add_nick(cm.sender);
No, saving in database won't be a good idea.. Remember you are saving details only for the length of the session and basic concept of database is to use it after the session. What happens if your session gets interruped because of network issues etc?
Just use Map instead of plain arrays, using key as client ID and value as username.. removing username will be a plain call such as map.remove(clientID);
EDIT AS YOU ASKED: Note that this code is not complete and only as much as you gave..
public class AddClient implements Runnable {
Thread t;
private Map<int, String> users = new HashMap <int, String>();
AddClient(String tot) {
t = new Thread(this, tot);
t.start();
}
public void run() {
while (true) {
try {
try {
waitClient();
} catch (Exception ex) {
ex.printStackTrace();
}
int clientId = users.size() + 1;
users.put(clientId, cm.sender);
//set stream to send and receive data
out[clientId] = new ObjectOutputStream(connect.getOutputStream());
out[clientId].flush();
in[clientId] = new ObjectInputStream(connect.getInputStream());
REMOVE USER METHOD
public synchronized void removeUser(int number) {
if(users.containsKey(number)) {
System.out.println("Server removing user " + users.get(number) + "which is client " + number);
users.remove(number);
} else {
System.out.println("User not in session");
}
}
Okay, I'm trying to create a custom client for Minecraft (don't worry, my question has nothing to do with Minecraft in particular), and I added an abstract class to manage a configuration file using Java's built-in Properties system. I have a method that loads a properties file or creates it if it doesn't already exist. This method is called at the beginning of all my other methods (although it only does anything the first time its called).
The properties file gets created just fine when I run Minecraft the first time, but somehow when I run it the second time, the file gets blanked out. I'm not sure where or why or how I'm wiping the file clean, can someone please help me? Here's my code; the offending method is loadConfig():
package net.minecraft.src;
import java.util.*;
import java.util.regex.*;
import java.io.*;
/**
* Class for managing my custom client's properties
*
* #author oxguy3
*/
public abstract class OxProps
{
public static boolean configloaded = false;
private static Properties props = new Properties();
private static String[] usernames;
public static void loadConfig() {
System.out.println("loadConfig() called");
if (!configloaded) {
System.out.println("loading config for the first time");
File cfile = new File("oxconfig.properties");
boolean configisnew;
if (!cfile.exists()) {
System.out.println("cfile failed exists(), creating blank file");
try {
configisnew = cfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
configisnew=true;
}
} else {
System.out.println("cfile passed exists(), proceding");
configisnew=false;
}
FileInputStream cin = null;
FileOutputStream cout = null;
try {
cin = new FileInputStream(cfile);
cout = new FileOutputStream(cfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!configisnew) { //if the config already existed
System.out.println("config already existed");
try {
props.load(cin);
} catch (IOException e) {
e.printStackTrace();
}
} else { //if it doesn't exist, and therefore needs to be created
System.out.println("creating new config");
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
try {
props.store(cout, "OXGUY3'S CUSTOM CLIENT\n\ncloak_url is the URL to get custom cloaks from\nnames are the usernames to give cloaks to\n");
cout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
String names = props.getProperty("names");
System.out.println("names: "+names);
try {
usernames = Pattern.compile(", ").split(names);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("usernames: "+Arrays.toString(usernames));
configloaded=true;
}
}
public static boolean checkUsername(String username) {
loadConfig();
System.out.println("Checking username...");
for (int i=0; i<usernames.length; i++) {
System.out.println("comparing "+username+" with config value "+usernames[i]);
if (username.startsWith(usernames[i])){
System.out.println("we got a match!");
return true;
}
}
System.out.println("no match found");
return false;
}
public static String getCloakUrl() {
loadConfig();
return props.getProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
}
}
If it's too hard to read here, it's also on Pastebin: http://pastebin.com/9UscXWap
Thanks!
You are unconditionally creating new FileOutputStream(cfile). This will overwrite the existing file with an empty one. You should only invoke the FileOutputStream constructor when writing a new config file.
if (configloaded)
return;
File cfile = new File("oxconfig.properties");
try {
if (cfile.createNewFile()) {
try {
FileOutputStream cout = new FileOutputStream(cfile);
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://...");
...
cout.flush();
} finally {
cout.close();
}
} else {
FileInputStream cin = new FileInputStream(cfile);
try {
props.load(cin);
} finally {
cin.close();
}
}
configloaded=true;
} catch(IOException ex) {
e.printStackTrace();
}