I have a shell and batch script to make specific calls to a MBean on a JMX server. The shell input args are not working in windows because windows handles " differently than linux.
Assuming this is a bean name : bean = "hostName=\"localhost\",name=\"foobar\"\""; and the whole input args on linux is something like this:
String[] params = new String[]{"-srv", "localhost:1234", "-usr", "foo", "-pwd", "bar", "-b", bean};
This works perfectly fine on a shell but not for windows.
I wrote one method to convert the bean name to be windows dos compliant. This is essentially accomplished by adding 2 double quotes to a single double quote and adding only 2 double quotes to two double quotes:
" -> """ and "" -> """"
public static void main(String[] args) throws Exception
{
String bean = "hostName=\"localhost\",name=\"foobar\"\"";
String[] params = new String[]{"-srv", "localhost:1234", "-usr", "foo", "-pwd", "bar", "-b", bean};
for ( int i = 0; i < params.length; i++)
{
if (params[i].equals("-b"))
{
// this is most likely the bean name
String beanName = params[i + 1];
StringBuilder dosCompliantName = new StringBuilder();
// commence magic to make double quotes (") correct for windows
for (int j = 0; j < beanName.length(); j++)
{
char c = beanName.charAt(j);
if (c == '"')
{
try
{
if (beanName.charAt(j + 1) != '"')
{
// this is only one double quote so we add 2 additional double quotes to it
dosCompliantName.append(c);
dosCompliantName.append(c);
dosCompliantName.append(c);
}
else if (beanName.charAt(j + 1) == '"')
{
// we have 2 double quotes here so we add only one because the next loop run will then also add only
// one and in the end we have 4 double quotes:
// "" -> """ -> """"
dosCompliantName.append(c);
dosCompliantName.append(c);
}
}
catch (StringIndexOutOfBoundsException e)
{
// we have reached the end and the last char was a double quote so we add 2
dosCompliantName.append(c);
dosCompliantName.append(c);
}
}
else
{
dosCompliantName.append(c);
}
}
System.out.println(dosCompliantName);
params[i + 1] = dosCompliantName.toString();
}
}
}
The input/output for Linux and Windows on the console should look like this:
Linux : hostName="localhost",name="foobar""
Windows:hostName="""localhost""",name="""foobar""""
This looks like to work but to me it looks terribly inefficient, ugly and the readability is also not really great. How can I improve this?
Note: of course this whole stuff is extracted into its own method but for the sack of demonstration I put it into the main method